多次匹配非捕获组

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

我真的很努力地取得好头衔,但是我不确定是否要问这个权利。这是我的最佳尝试:

我正在使用python的regex样式

我需要使用命名组匹配数字:

15x20x30    ->  'values': [15,20,30]
15bits      ->  'values': [15]
15          ->  'values': [15]
x15         ->  'values': [15]

但不应该匹配:

456.48
888,12
6,4.8,4684.,6

到目前为止,我最大的尝试是:

((?:[\sa-z])(?P<values>\d+)(?:[\sa-z]))
  • 我使用[\sa-z]而不是字边界,因为15x20是两个不同的值。

但是对于15x20情况,它不能同时匹配15和20。如果在15x 20中放入多余的空间,它确实可以工作。我如何告诉它在结束时“重置”非捕获组,以便它在开始时也可用于非捕获组?

python regex python-regex
1个回答
1
投票

您可以使用

(?<![^\sa-z])\d+(?![^\sa-z])

不区分大小写的版本:

(?i)(?<![^\sa-z])\d+(?![^\sa-z])

或者,用re.I / re.IGNORECASE标志编译模式。

请参见regex demo

详细信息

  • [(?<![^\sa-z])-如果在紧靠左侧,没有空格或小写字母(如果使用(?i)re.I,则使用任何ASCII字母]),则负向后查找将使匹配失败。
  • \d+-1个以上的数字
  • [(?![^\sa-z])-如果在紧靠右侧,没有空格或小写字母(如果使用(?i)re.I,则使用任何ASCII字母]),则匹配失败的否定前行]

0
投票

仅说明您的模式为何不匹配15x20x30,在您使用的模式中,您要提取以\d+开头的\s or a-z但您忘了它可以在行的开头,因此如果^ or \s or a-z开头,则需要检查它,并匹配数字序列之后的内容,您也应该在文本末尾添加\s or a-z or $,您需要使用正数lookahead来占用\d+之后的字符。

text = """
15x20x30
15bits
15
x15
456.48
888,12
6,4.8,4684.,6
"""

RE_EXTRACT_VALUES = '(?:[\sa-z]|^)(\d+)(?=[\sa-z]|$)'

# extract value line by line
for line in text.strip().split('\n'):
    values = re.findall(RE_EXTRACT_VALUES, line)
    if values:
        print(values)

# extract all value using findall directly
print(re.findall(RE_EXTRACT_VALUES, text))  # ['15', '20', '30', '15', '15', '15']

无法使用dict groups提取所有值,应使用re.findall,如果使用searchmatch,则组将仅返回第一个匹配项。

(?<![^\sa-z])\d+(?![^\sa-z])建议的模式@WiktorStribiżew在这里做同样的事情。

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