正则表达式使用 finditer 跨越多行

问题描述 投票:0回答:1

我正在开发一个正则表达式,它将日志解析成组以写入 df. 某些日志事件会跨越多行。 我正在做这个jupyter笔记本

我正在尝试找到一个正则表达式,它期待以时间戳开头的下一行的开始。

我不确定正则表达式是否能让我跳过多行。

这会失败,并在接近尾声的展望中出现“新行”。

regex = re.compile(
    '(?P<time>(\d{2}\:\d{2}\:\d{2}.\d{3}))'
    '(?P<a>\s(\[T\:))?'
    '(?P<token>\d{15})?'
    '(?P<b>(\]\s{))?'
    '(?P<event_type>.*\:\d)?'
    '(?P<c>\}\s)'
    '(?P<message>.*)'
    '(?=^\d{2}\d{2})'

这可以工作,但会破坏 \d{2}\d{2} 处的最后一条消息,但它必须位于同一行,而不是下一行。

regex = re.compile(
    '(?P<time>(\d{2}\:\d{2}\:\d{2}.\d{3}))'
    '(?P<a>\s(\[T\:))?'
    '(?P<token>\d{15})?'
    '(?P<b>(\]\s{))?'
    '(?P<event_type>.*\:\d)?'
    '(?P<c>\}\s)'
    '(?P<message>.*)'
    '(?=\d{2}\d{2})'

我正在用这个测试正则表达式:

with open(ors_log) as f:
    for m in regex.finditer(f.read()):
        if m:
            print(m.group('time', 'a', 'token', 'b', 'event_type', 'c', 'message'))

我已经尝试过 stackoverflow 的建议:

with open(ors_log) as f:
    for m in regex.finditer(f.read(), re.MULTILINE):

(?=\n\d{2}\d{2})')

非常感谢任何想法,谢谢。

15:36:32.448 [T:140113529200000] {ScxmlMetric:3} METRIC <log sid='~456~1TF8DKFD49SRE6Q9PE0C2LAES00000J' expr='~456~01TF8DKFD49SRE6Q9PE0C2LAES00000J: Inside Screen Block: Priorities' label='' level='2' />
15:36:32.448 [T:14011340184339] {ScxmlMetric:1} METRIC <extension sid='~456~01TF8DKFD49we4rf5g6h7C2LAES00000J' name='screen' namespace='https://lab.io/modules' />
15:36:32.448 ==>Connector::ConnHandler  Port=0 Proto=0 CallBack=<9740>
===>event:   event_id=3, id=0 handle=66, datasize=24 
15:36:32.448 {Thread:3} HandleThreadData: << 24 bytes <<
15:36:32.448 {Link:3} Message 'request' sent to 'IP'
    attr_ref_id [int] = 999530875
    attr_envelope [list, size (unpacked)=369] = 
       'Version' [str] = "1.0"
       'AppType' [int] = 90
       'Service' [str] = "Screen"
15:36:34.222 {ThreadSync:3} HandleThreadData: << 24 bytes <<

消息1

METRIC <log sid='~456~1TF8DKFD49SRE6Q9PE0C2LAES00000J' expr='~456~01TF8DKFD49SRE6Q9PE0C2LAES00000J: Inside Screen Block: Priorities' label='' level='2' />

消息2

METRIC <extension sid='~456~01TF8DKFD49we4rf5g6h7C2LAES00000J' name='screen' namespace='https://lab.io/modules' />

消息3

==>Connector::ConnHandler   Port=0 Proto=0 CallBack=<9740>
===>event:   event_id=3, id=0 handle=66, datasize=24 

消息4

HandleThreadData: << 24 bytes <<

消息5

Message 'request' sent to 'IP'
    attr_ref_id [int] = 999530875
    attr_envelope [list, size (unpacked)=369] = 
       'Version' [str] = "1.0"
       'AppType' [int] = 90
       'Service' [str] = "Screen"

消息6

HandleThreadData: << 24 bytes <<
python regex-group regex-lookarounds
1个回答
0
投票

获取 4 个命名捕获组的数据以及

message
的多行数据:

(?P<time>\d{2}:\d{2}:\d{2}\.\d{3})(?:\s\[T:(?P<token>\d{14,})])?(?:\s{(?P<event_type>[^:]+:\d+)})?(?P<message>.*(?:\n(?!\d{2}:\d{2}\:\d{2}\.\d{3}\b).*)*)

模式匹配:

  • (?P<time>\d{2}:\d{2}:\d{2}\.\d{3})
    命名组time(注意要转义点
    \.
    ,并且不必转义
    :
  • (?:\s\[T:(?P<token>\d{14,})])?
    可选组,匹配
     [T:
    并在命名组中捕获 token 匹配 14 个或更多数字(或
    {15}
    ,如果始终为 15 并且示例数据中存在拼写错误)
  • (?:\s{(?P<event_type>[^:]+:\d+)})?
    可选组,匹配
     {
    ,然后在组中捕获 event_type 1+ 个除
    :
    之外的字符,然后
    :
    和 1+ 个数字并匹配结束的
    }
  • (?P<message>
    已命名群组 消息
    • .*
      匹配整行
    • (?:\n(?!\d{2}:\d{2}\:\d{2}\.\d{3}\b).*)*
      匹配所有不以类似时间模式开头的以下行
  • )
    关闭群组

查看 正则表达式演示

注意这里有14位数字而不是15位

[T:14011340184339]

© www.soinside.com 2019 - 2024. All rights reserved.