【问题标题】:How to fix my Regex pattern to get 3 blocks of values如何修复我的正则表达式模式以获取 3 个值块
【发布时间】:2020-03-04 20:43:06
【问题描述】:

我有 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 个字段,但服务块将始终存在,但可以是任何长度

【问题讨论】:

  • 请详细说明期望的结果是什么
  • 期望的结果几乎就像 my_regex2 一样,但在 line2 的计数器块末尾没有额外的“:”。
  • 用人类语言解释你想要分割字符串的条件是什么。我可能是您创建了一个错误的正则表达式,并且需要明确您想要完成什么。
  • @Dmitriy 像这样试试^(?P&lt;acc&gt;[^\r\n;]+(?:;[^\r\n;]+){4});(?:(?P&lt;counters&gt;.+?:):)?\[\!\]:(?P&lt;services&gt;.*):;1;$regex101.com/r/8vmN1I/1
  • @Thefourthbird 谢谢!成功了!

标签: python regex parsing


【解决方案1】:

如果您不想在 counters 组中使用第二个双引号,您可以更新模式以匹配 counters 组中的第一个 : 并匹配紧跟在该组之后的第二个。

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

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

部分

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

Regex demo

【讨论】:

    【解决方案2】:
    answer1 = "^(?P<acc>[^\r\n;]+(?:;[^\r\n;]+){4});(?:(?P<counters>.+?:):)?\[\!\]:(?P<services>.*):;1;$"
    answer2 = "^(?P<acc>(?:[^;]+;){4}[^;]+);(?:(?P<counters>.*?):)?\[!]:(?P<services>.*):;1;$"
    

    【讨论】:

      猜你喜欢
      • 2022-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-03
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多