首页 > 解决方案 > 如何修复我的正则表达式模式以获取 3 个值块

问题描述

我有 2 种线可以用单个正则表达式打破 3 组

line1 = """NAME1;address;10461;427144.70;012020;244312:countername1::244312:countername2::244312:countername3::[!]:1:service1:410630.15:62:penny:16514.55:;1;"""

line2 = """NAME2;ADDRESS2;10458;1853.12;012020;[!]:1:service1:1853.12:62:penny:0.00:;1;"""

my_regex1 = r'^(?P<acc>.+;.+;.+;.+;.+);(?P<counters>.*:?.*):\[\!\]:(?P<services>.*):;1;$'

my_regex2 = r'^(?P<acc>.+;.+;.+;.+;.+);(?P<counters>.*:){0,}:?\[\!\]:(?P<services>.*):;1;$'

line1 上的第一个正则表达式的结果是好的,有点像 line2 上的失败

    re.findall(my_regex1, line1) >>> 
[('NAME1;address;10461;427144.70;012020',     '244312:countername1::244312:countername2::244312:countername3:', '1:service1:410630.15:62:penny:16514.55')]

但它根本没有赶上line2

第二个正则表达式中断第 2 行,但在第 1 行出现计数器块失败

    re.findall(my_regex2, line2) >>> [('NAME2;ADDRESS2;10458;1853.12;012020', '', '1:service1:1853.12:62:penny:0.00')] #which s ok, but it fails with line2

re.findall(my_regex2, line1)

 >>>
    [('NAME1;address;10461;427144.70;012020','244312:countername1::244312:countername2::244312:countername3::','1:service1:410630.15:62:penny:16514.55')]     

我需要修复 regex2 以便它可以正确中断所有行,现在它在块的末尾添加不需要的“:”字符失败,计数器块可能根本不存在或有超过 9 个字段,但服务块将始终存在但可以是任何长度

标签: pythonregexparsing

解决方案


如果您不希望 counters 组中的第二个双引号,您可以更新模式以匹配:counters 组中的第一个,并匹配紧跟该组的第二个。

请注意,.+;它将首先匹配到行尾,并且可以使用[^\r\n;]+;匹配除 a 或换行符之外的任何字符的否定字符类来编写;,以防止交叉换行符。

^(?P<acc>[^\r\n;]+(?:;[^\r\n;]+){4});(?:(?P<counters>.+?:):)?\[\!]:(?P<services>.*):;1;$

在零件

  • ^字符串的开始
  • (?P<acc>命名组acc
    • [^\r\n;]+匹配除换行符以外的任何字符的 1 次以上或;
    • (?:;[^\r\n;]+){4}重复 4 次匹配;和 1 次以上除;换行符以外的任何字符
  • );关闭组和匹配;
  • (?:非捕获组
    • (?P<counters>.+?:):组后的命名组counters(匹配第二个:
  • )?关闭组并使其可选
  • \[\!]:匹配[!]:
  • (?P<services>.*)命名组services,匹配 0+ 次除换行符以外的任何字符
  • :;1;从字面上匹配
  • $字符串结束

正则表达式演示


推荐阅读