regex 如何将所有空格标识为分隔符,直到通过两次双点

mdfafbf1  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(133)

我试图找到一个正则表达式,它应该满足以下需求。
它应该将所有空格标识为分隔符,直到双点被传递2次。在这一遍之后,它应该继续使用空格作为分隔符,直到识别出第三个双点。第三个冒号也应该用作分隔符。但是这个特定冒号前后的所有空格都不应该用作分隔符。在识别出这个特殊的双点之后,就不应该再找到分隔符了,即使它是一个空格或冒号。

2019-12-28 13:00:00.112 DEBUG n-somethingspecial.at --- [9999-118684] 3894ß8349ß84930ßaa14e38eae18e3ebf c.w.f.w.NiceController             : z rest as async texting: json, special character, spacses.....

我希望将分隔符标识如下(分隔符显示为X)

2019-12-28X13:00:00.112XDEBUGXn-somethingspecial.atX---X[9999-118684]X3894ß8349ß84930ßaa14e38eae18e3ebfXc.w.f.w.NiceControllerXz rest as async texting: json, special character, spacses.....

2019-12-28 X 13:00:00.112 X DEBUG X n-somethingspecial.at X --- X [9999-118684] X 3894ß8349ß84930ßaa14e38eae18e3ebf X c.w.f.w.NiceController X z rest as async texting: json, special character, spacses.....

在这里发现了8个分离器。
如何通过正则表达式实现这一点?
我目前的方法不工作,因为我试图这样做如下

(?<=\d{4}-\d{2}-\d{2})\s|(?<=\d{2}:\d{2}:\d{2}\.\d{3})\s|(?<=DEBUG)\s|(?<=\s---)\s|(?<=WARN)\s|(?<=ERROR)\s|(?<=\[[0-9a-z\#\.\-]{15}\])\s|((?<=\[[0-9a-z\#\.\-]{15}\]\s)\s|(?<=\[[0-9a-z\#\.\-]{15}\]\s[a-z0-9]{32})\s)|\s(?=---)|(?<=[a-zA-Z])\s+\:\s

这是我目前用来标识分隔符的语法。上面的正则表达式有错误。

(?<=\d{4}-\d{2}-\d{2})\s|(?<=\d{2}:\d{2}:\d{2}\.\d{3})\s|(?:(?<=DEBUG)\s|(?<=WARN)\s|(?<=ERROR)\s|(?<=INFO)\s)|(?<=(?:p|t)-.{7}\-.{5}\.domain\.sys)\s|(?<=\s---)\s|(?<=\[[\s0-9a-z\#\.\-]{15}\])\s|(?:(?<=\[[\s0-9a-z\#\.\-]{15}\]\s)\s|(?<=[a-z0-9]{32})\s)|\s+\:\s(?<=[\sa-z]{1}\s{1}\:\s{1})

这是当前正则表达式。Targetapproach是调用

df = pd.read_csv(file_name,
                         sep="(?<=\d{4}-\d{2}-\d{2})\s|(?<=\d{2}:\d{2}:\d{2}\.\d{3})\s|(?:(?<=DEBUG)\s|(?<=WARN)\s|(?<=ERROR)\s|(?<=INFO)\s)|(?<=(?:p|t)-.{7}\-.{5}\.domain\.sys)\s|(?<=\s---)\s|(?<=\[[\s0-9a-z\#\.\-]{15}\])\s|(?:(?<=\[[\s0-9a-z\#\.\-]{15}\]\s)\s|(?<=[a-z0-9]{32})\s)|\s+\:\s(?<=[\sa-z]{1}\s{1}\:\s{1})",
                         names=['date', 'time', 'level', 'host', 'template', 'threadid', 'logid', 'classmethods', 'line'],
                         engine='python',
                         nrows=100)

这可以在以后扩展到dask,这使我可以在一个 Dataframe 中解析多个日志文件。
未正确标识最后一列行。原因不明。

mm5n2pyu

mm5n2pyu1#

如果日志格式足够规则,则可以使用str.split更容易地拆分行。
假设前八个字段都没有内部空格,并且它们都总是存在(或者,如果不是所有字段都存在,则最后一个字段(从冒号开始)也不存在)。然后,您可以使用maxsplit参数到str.split,以便在第九个字段开始时停止拆分:

def separate(logline):
    fields = logline.split(maxsplit=8) # 8 space separate fields + the rest
    if len(fields) > 8:
        # Fix up the ninth field. Perhaps you want to remove the colon:
        fields[8] = fields[8][1:]
        # or perhaps you want the text starting at the first non-whitespace
        # character after the colon:
        #
        # if fields[8][0] == ':':
        #      fields[8] = fields[8].split(maxsplit=1)[1]
        #
        # etc.
    return fields

>>> logline = ( "2019-12-28 13:00:00.112 DEBUG n-somethingspecial.at"
...           + " --- [9999-118684] 3894ß8349ß84930ßaa14e38eae18e3ebf"
...           + " c.w.f.w.NiceController"
...           + "             : z rest as async texting: json, special character, spaces.....")
>>> separate(logline)
['2019-12-28', '13:00:00.112', 'DEBUG', 'n-somethingspecial.at', '---',
 '[9999-118684]', '3894ß8349ß84930ßaa14e38eae18e3ebf',
 'c.w.f.w.NiceController',
 ' z rest as async texting: json, special character, spaces.....']
lndjwyie

lndjwyie2#

  • 解决方案 *

我的问题的当前结果可以通过下面的正则表达式来解决。

(?:(?<=\d{4}-\d{2}-\d{2})\s|(?<=\d{2}:\d{2}:\d{2}\.\d{3})\s|(?:(?<=DEBUG)\s|(?<=WARN)\s|(?<=ERROR)\s|(?<=INFO)\s)|(?<=(?:p|t)-.{7}\-.{5}\.hostname\.sys)\s|(?<=\s---)\s|(?<=\[[\s0-9a-z\#\.\-]{15}\])\s|(?:(?<=\[[\s0-9a-z\#\.\-]{15}\]\s)\s|(?<=[a-z0-9]{32})\s))|\s+\:\s(?<=[\sa-z]{1}\s{1}\:\s{1})

也许要做一些小的调整,也许,但现在它的工作相当不错。

相关问题