我真的很努力地取得好头衔,但是我不确定是否要问这个权利。这是我的最佳尝试:
我正在使用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
中放入多余的空间,它确实可以工作。我如何告诉它在结束时“重置”非捕获组,以便它在开始时也可用于非捕获组?
您可以使用
(?<![^\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字母]),则匹配失败的否定前行]仅说明您的模式为何不匹配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
,如果使用search
或match
,则组将仅返回第一个匹配项。
注:(?<![^\sa-z])\d+(?![^\sa-z])
建议的模式@WiktorStribiżew
在这里做同样的事情。