在正则表达式匹配中提取分组

13

我有一组输入内容。 我正在尝试编写一个正则表达式以匹配以下输入中的模式:

日期时间地点

示例输入:

今天下午12:30山姆的客厅

文本中加粗的部分在每个输入中都不同。

我编写了以下正则表达式:

import regex as re

input_example = "Today at 12:30 PM on Rakesh's Echo"
regexp_1 = re.compile(r'(\w+) at (\d+):(\d+) (\w+) on (\w+)')
re_match = regexp_1.match(input_example)

现在我的代码可以匹配正确的模式,接下来我想从这些模式中提取出组。

我的期望输出是:

re_match.group(1)
>> "Today"
re_match.group(2)
>> "12:30 PM"
re_match.group(3)
>> "Sam's living room"

然而,我当前的正则表达式匹配并没有给出这个输出。请问正确的正则表达式是什么,可以给我上述的输出?


当你说它没有给出那个输出时,它实际上给出了什么输出?我可以想象从这里第三组只是“Sam”,但还有什么? - moopet
3个回答

13

你可以创建嵌套组,但这样会使得可读性变差,因为你需要计算组的确切数量,然后你会忘记那个数字具体表示什么。

最好使用命名组。这是从 REPL 复制的:

>>> import re
... 
... input_example = "Today at 12:30 PM on Rakesh's Echo"
... regexp_1 = re.compile(r'(?P<day>\w+) at (?P<time>(\d+):(\d+) (\w+)) on (?P<place>\w+)')
... re_match = regexp_1.match(input_example)
>>> list(re_match.groups())
['Today', '12:30 PM', '12', '30', 'PM', 'Rakesh']
>>> re_match.group('day')
'Today'
>>> re_match.group('time')
'12:30 PM'
>>> re_match.group('place')
'Rakesh'

使用方法在示例中非常明显,但在re的文档中也有说明这里,使用ctrl-f搜索"(?P<name>...)"即可。 - dasWesen

7
你已经很接近了。你只需要稍微调整一下你的捕获组,看起来像这样...注意第二个捕获组现在将匹配完整的“小时:分钟-白天时间段”。最后一个捕获组“(\w+)”将匹配a-z、A-Z、0-9和_,但不包括',这会导致你只捕获到一小部分描述。对“.+”进行更改可以使其匹配任何字符。如果你知道除\w之外的只有几个字符需要匹配,那么你可以使用“[\w'] +”以及其他你需要包含的字符。
一个很好的工具,可以用来测试你的正则表达式,是https://regex101.com/,确保你选择了Python语言。

2
另一个很棒的工具:https://pythex.org/ 如果存在无匹配的可能性(例如AM / PM是可选的),请将+替换为星号,即r"(\w+) at (\d+:\d+ \w*) on (.+)" - Lauren Oldja

1

我认为你需要使用re.compile(r'(\w+) at (\d+:\d+ \w+) on (.+)')

你的第二个组需要捕获整个时间(两个数字和一个单词),而你的第三个组需要接受不仅仅是\w,如果你想获取撇号等字符。我建议使用.+,它将获取到行尾的所有内容。

我已经尝试过这个方法,并得到了以下结果:

今天

12:30 PM

Rakesh's Echo


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