Python:非捕获组在正则表达式中无法使用

3

我在正则表达式中使用非捕获组,即(?:.*),但它不起作用。

我仍然能够在结果中看到它。如何忽略它/不在结果中捕获?

代码:

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')

移除 (?:.*) https://regex101.com/r/X69k0V/1 并且如果数字不能为可选项则为 (?P<pr>Pt\s{3}\d+(?:\.\d+)?\s[a-z]+) - The fourth bird
@Thefourthbird 在这个模式之前还有一个我想要捕获的组。因此,无法删除它。 - shaik moeed
你想在之前捕获什么?像这样吗?.*\b(?P<pr>Pt\s{3}\d+(?:\.\d+)?\s[a-z]+) https://regex101.com/r/sA3atN/1 - The fourth bird
1
像这样吗?(?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]+) https://regex101.com/r/dQULqz/1 - The fourth bird
3个回答

1
量词在命名组内部,你需要将其放在外面,并可能使其非贪婪。
更新后的模式可能如下所示:
(?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> 时间组 time
  • \d\d:\d\d:\d\d.\d{3} 匹配时间格式
  • )\s 关闭组并匹配一个空格字符
  • (?P<date> 日期组 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 字符
  • ) 关闭组

{{链接1:正则表达式演示}}


谢谢你的回答。为什么要在十进制数中添加非捕获组,即 (?:\.\d+) - shaik moeed
1
这意味着您首先匹配一个或多个数字,然后可选择匹配一个点和一个或多个数字。因此,非捕获组使匹配点和接下来的数字作为整体是可选的,以防止例如匹配 123. - The fourth bird

1

从你的命名组中移除非捕获组。使用非捕获组意味着在匹配中不会创建新的组,而不是将该字符串部分从任何包含组中删除。

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

请注意,您使用的特定非捕获组可以完全排除,因为它基本上意味着您希望您的正则表达式被任何东西先行,而这正是search将要做的。

谢谢解释。在pr组之前加一个非捕获组后它工作了。 - shaik moeed

0

我认为在“非捕获”这个概念上存在一些混淆:它并不意味着结果会省略此部分,而是在结果中不会创建任何匹配组。

以下是使用捕获组和非捕获组执行相同正则表达式的示例:

>>> 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包含完整字符串的匹配部分)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接