【问题标题】:Regex having optional groups with non-capturing groups正则表达式具有可选组和非捕获组
【发布时间】:2021-12-14 19:41:09
【问题描述】:

我有一个包含多个可选组和非捕获组的正则表达式。所有这些组都可以发生,但不是必须的。正则表达式应使用非捕获组到return the whole string

当我将最后一组也设置为可选时,正则表达式将有几个分组结果。当我将第一组设置为非可选时,正则表达式匹配。这是为什么呢?

输入类似于input_text = "xyz T1 VX N1 ",预期输出T1 VX N1

regexs = {
    "allOptional": 'p?(?:T[X0-4]?)?\\s?(?:V[X0-2])?\\s?(?:N[X0-3])?',
    "lastNotOptional": 'p?(?:T[X0-4]?)?\\s?(?:V[X0-2])?\\s?(?:N[X0-3])',
    "firstNotOptional": 'p?(?:T[X0-4]?)\\s?(?:V[X0-2])?\\s?(?:N[X0-3])?',
}

for key, regex in regexs.items():
    matches = re.findall(regex, input_text)

    # Results
    allOptional = ['', '', '', ' ', 'T1 VX N1', '']
    lastNotOptional = ['T1 VX N1']
    firstNotOptional = ['T1 VX N1']

提前致谢!

【问题讨论】:

  • 非捕获组不返回任何内容。
  • p?(?:T[X0-4]?)?\s?(?:V[X0-2])?\s?(?:N[X0-3])? all 选项将匹配每个字符位置。这应该避免,因为它也包括琐碎的解决方案。
  • 您可以通过要求 ^(?![\s]*$)p?(?:T[X0-4]?)?\s?(?:V[X0-2])?\s?(?:N[X0-3])?$ 来避免琐事,这会强制它匹配非空白字符,同时允许所有段都是可选的。
  • 你能提供 input_text 吗?似乎正则表达式匹配,因为您的 input_text 中有这个组。
  • 之前之后,中间,只要其中一个可选的东西就行了,真的没关系。甚至可以取消匹配其他任何东西(?=(?:p|T[X0-4]?|V[X0-2]|N[X0-3]))p?(?:T[X0-4]?)?[ \t]?(?:V[X0-2])?[ \t]?(?:N[X0-3])?

标签: python regex


【解决方案1】:

我建议

\b(?=\w)p?(?:T[X0-4]?)?\s?(?:V[X0-2])?\s?(?:N[X0-3])?\b(?<=\w)

the regex demo

对此的替代方案是环视组合,确保匹配前面紧跟空白字符或字符串开头,匹配的第一个字符是空白字符,以及另一个环视组合(在模式)以确保匹配结束字符是非空格,然后是空格或字符串结尾:

(?<!\S)(?=\S)p?(?:T[X0-4]?)?\s?(?:V[X0-2])?\s?(?:N[X0-3])?(?!\S)(?<=\S)

this regex demo

这里的要点是两个特定的单词/空白边界:

  • \b(?=\w) 在开头确保单词边界位置匹配,即紧跟单词 char
  • 末尾的\b(?&lt;=\w) 断言单词边界处的位置,左侧紧邻单词 char
  • (?&lt;!\S)(?=\S) - 位于字符串开头的位置,或紧跟在空格之后且紧跟非空白字符的位置
  • (?!\S)(?&lt;=\S) - 位于字符串末尾的位置,或紧接在空白之前且紧接在非空白字符之前的位置。

查看Python demo

import re
input_text = "xyz T1 VX N1 G1"
pattern = r'\b(?=\w)p?(?:T[X0-4]?)?\s?(?:V[X0-2])?\s?(?:N[X0-3])?\b(?<=\w)'
print(re.findall(pattern, input_text))
# => ['T1 VX N1']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-21
    • 2018-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多