Python: 非捕获组在 Regex 中不起作用
Python: Non capturing group is not working in Regex
我在正则表达式中使用非捕获组,即 (?:.*)
但它不起作用。
我仍然可以在结果中看到它。如何忽略结果中的 it/not 捕获?
代码:
import re
text = '12:37:25.790 08/05/20 Something P LR 0.156462 sccm Pt 25.341343 psig something-else'
pattern = ['(?P<time>\d\d:\d\d:\d\d.\d\d\d)\s{1}',
'(?P<date>\d\d/\d\d/\d\d)\s',
'(?P<pr>(?:.*)Pt\s{3}\d*[.]?\d*\s[a-z]+)'
]
result = re.search(r''.join(pattern), text)
输出:
>>> result.group('pr')
'Something P LR 0.156462 sccm Pt 25.341343 psig'
预期输出:
'Pt 25.341343 psig'
更多信息:
>>> result.groups()
('12:37:25.790', '08/05/20', 'Something P LR 0.156462 sccm Pt 25.341343 psig')
我觉得这里“non-capturing”的意思有点混淆:不是说结果省略了这部分,而是说结果里没有创建匹配组。
使用捕获和 non-capturing 组执行相同正则表达式的示例:
>>> import re
>>> match = re.search(r'(?P<grp>foo(.*))', 'foobar')
>>> match.groups()
('foobar', 'bar')
>>> match = re.search(r'(?P<grp>foo(?:.*))', 'foobar')
>>> match.groups()
('foobar',)
请注意 match.group(0)
在这两种情况下是相同的(第 0 组包含完整的字符串匹配部分)。
从您命名的组中删除 non-capturing 组。使用 non-capturing 组意味着不会在匹配中创建新组,而不是字符串的那部分将从任何包含的组中删除。
import re
text = 'Something P LR 0.156462 sccm Pt 25.341343 psig something-else'
pattern = r'(?:.*)(?P<pr>Pt\s{3}\d*[.]?\d*\s[a-z]+)'
result = re.search(pattern, text)
print(result.group('pr'))
输出:
Pt 25.341343 psig
请注意,您使用的特定 non-capturing 组可以完全排除,因为它基本上意味着您希望正则表达式前面有任何内容,而这正是 search
无论如何都会做的。
量词在命名组内,您必须将它放在外面,并可能使其不贪心。
更新后的模式可能如下所示:
(?P<time>\d\d:\d\d:\d\d.\d\d\d)\s{1}(?P<date>\d\d/\d\d/\d\d)\s.*?(?P<pr>Pt\s{3}\d*[.]?\d*\s[a-z]+)
注意在当前模式下,数字是可选的,因为所有量词都是可选的。您也可以省略 {1}
。
如果 Pt 后面的数字不能为空,可以使用 \d+(?:\.\d+)?
至少匹配一个数字来更新模式:
(?P<time>\d\d:\d\d:\d\d.\d{3})\s(?P<date>\d\d/\d\d/\d\d)\s.*?(?P<pr>Pt\s{3}\d+(?:\.\d+)?\s[a-z]+)
(?P<time>
组时间
\d\d:\d\d:\d\d.\d{3}
匹配时间格式
)\s
关闭组并匹配一个空白字符
(?P<date>
组日期
\d\d/\d\d/\d\d
匹配类似模式的日期
)\s
关闭组并匹配一个空白字符
.*?
尽可能匹配除换行符外的任何字符
(?P<pr>
组pr
Pt\s{3}
匹配 Pt 和 3 个空白字符
\d+(?:\.\d+)?
匹配 1+ 个带可选小数部分的数字
\s[a-z]+
匹配一个空白字符 1+ 次字符 a-z
)
关闭群组
我在正则表达式中使用非捕获组,即 (?:.*)
但它不起作用。
我仍然可以在结果中看到它。如何忽略结果中的 it/not 捕获?
代码:
import re
text = '12:37:25.790 08/05/20 Something P LR 0.156462 sccm Pt 25.341343 psig something-else'
pattern = ['(?P<time>\d\d:\d\d:\d\d.\d\d\d)\s{1}',
'(?P<date>\d\d/\d\d/\d\d)\s',
'(?P<pr>(?:.*)Pt\s{3}\d*[.]?\d*\s[a-z]+)'
]
result = re.search(r''.join(pattern), text)
输出:
>>> result.group('pr')
'Something P LR 0.156462 sccm Pt 25.341343 psig'
预期输出:
'Pt 25.341343 psig'
更多信息:
>>> result.groups()
('12:37:25.790', '08/05/20', 'Something P LR 0.156462 sccm Pt 25.341343 psig')
我觉得这里“non-capturing”的意思有点混淆:不是说结果省略了这部分,而是说结果里没有创建匹配组。
使用捕获和 non-capturing 组执行相同正则表达式的示例:
>>> import re
>>> match = re.search(r'(?P<grp>foo(.*))', 'foobar')
>>> match.groups()
('foobar', 'bar')
>>> match = re.search(r'(?P<grp>foo(?:.*))', 'foobar')
>>> match.groups()
('foobar',)
请注意 match.group(0)
在这两种情况下是相同的(第 0 组包含完整的字符串匹配部分)。
从您命名的组中删除 non-capturing 组。使用 non-capturing 组意味着不会在匹配中创建新组,而不是字符串的那部分将从任何包含的组中删除。
import re
text = 'Something P LR 0.156462 sccm Pt 25.341343 psig something-else'
pattern = r'(?:.*)(?P<pr>Pt\s{3}\d*[.]?\d*\s[a-z]+)'
result = re.search(pattern, text)
print(result.group('pr'))
输出:
Pt 25.341343 psig
请注意,您使用的特定 non-capturing 组可以完全排除,因为它基本上意味着您希望正则表达式前面有任何内容,而这正是 search
无论如何都会做的。
量词在命名组内,您必须将它放在外面,并可能使其不贪心。
更新后的模式可能如下所示:
(?P<time>\d\d:\d\d:\d\d.\d\d\d)\s{1}(?P<date>\d\d/\d\d/\d\d)\s.*?(?P<pr>Pt\s{3}\d*[.]?\d*\s[a-z]+)
注意在当前模式下,数字是可选的,因为所有量词都是可选的。您也可以省略 {1}
。
如果 Pt 后面的数字不能为空,可以使用 \d+(?:\.\d+)?
至少匹配一个数字来更新模式:
(?P<time>\d\d:\d\d:\d\d.\d{3})\s(?P<date>\d\d/\d\d/\d\d)\s.*?(?P<pr>Pt\s{3}\d+(?:\.\d+)?\s[a-z]+)
(?P<time>
组时间\d\d:\d\d:\d\d.\d{3}
匹配时间格式)\s
关闭组并匹配一个空白字符(?P<date>
组日期\d\d/\d\d/\d\d
匹配类似模式的日期
)\s
关闭组并匹配一个空白字符.*?
尽可能匹配除换行符外的任何字符(?P<pr>
组prPt\s{3}
匹配 Pt 和 3 个空白字符\d+(?:\.\d+)?
匹配 1+ 个带可选小数部分的数字
\s[a-z]+
匹配一个空白字符 1+ 次字符 a-z)
关闭群组