Python正则表达式查找所有匹配项

48

我正在尝试使用Python 2.7.2中的正则表达式从字符串中提取所有标记词的出现次数。或者简单地说,我想提取在[p][/p]标记中的每一个文本片段。

这是我的尝试:

regex = ur"[\u005B1P\u005D.+?\u005B\u002FP\u005D]+?"
line = "President [P] Barack Obama [/P] met Microsoft founder [P] Bill Gates [/P], yesterday."
person = re.findall(pattern, line)

打印person会产生['总统[P]', '[/P]', '[P]比尔·盖茨[/P]']

正确的正则表达式是什么,以获得:['[P]巴拉克·奥巴马[/P]', '[P]比尔·盖茨[/P]']['巴拉克·奥巴马', '比尔·盖茨']

5个回答

73
import re
regex = ur"\[P\] (.+?) \[/P\]+?"
line = "President [P] Barack Obama [/P] met Microsoft founder [P] Bill Gates [/P], yesterday."
person = re.findall(regex, line)
print(person)
产生结果。
['Barack Obama', 'Bill Gates']
正则表达式 ur"[\u005B1P\u005D.+?\u005B\u002FP\u005D]+?" 是与 u'[[1P].+?[/P]]+?' 完全相同的Unicode编码,只是更难以阅读。
第一个方括号组 [[1P] 告诉 re 任何在列表 ['[', '1', 'P'] 中的字符都应该匹配,第二个方括号组 [/P]] 同理。这完全不是你想要的。因此,您需要:
  • 删除外部包围的方括号。(还要删除在 P 前面的杂乱无章的 1。)
  • 为了保护 [P] 中的文字,需要用反斜杠转义括号:\[P\]
  • 如果要返回标签内的单词,请将 .+? 放在分组括号中。

16

试试这个:

   for match in re.finditer(r"\[P[^\]]*\](.*?)\[/P\]", subject):
        # match start: match.start()
        # match end (exclusive): match.end()
        # matched text: match.group()

1
我真的很喜欢这个答案。如果你只想处理匹配项,那么这个方法可以做到,而且不需要额外的语句,比如1)保存列表,2)处理列表。这难道不等同于str = '紫色 alice@google.com,嘟嘟猴 bob@abc.com 嘟嘟洗碗机'?

在这里,re.findall()会返回一个包含所有找到的电子邮件字符串的列表

emails = re.findall(r'[\w.-]+@[\w.-]+', str) ## ['alice@google.com', 'bob@abc.com']for email in emails: # 对每个找到的电子邮件字符串进行操作 print email
- kkron

4

您的问题不是非常清楚,但我假设您想要找到在[P][/P]标签中间的所有文本:

>>> import re
>>> line = "President [P] Barack Obama [/P] met Microsoft founder [P] Bill Gates [/P], yesterday."
>>> re.findall('\[P\]\s?(.+?)\s?\[\/P\]', line)
['Barack Obama', 'Bill Gates']

2
您可以将您的模式替换为:
regex = ur"\[P\]([\w\s]+)\[\/P\]"

注意你的格式;使用预览区域。因为你没有正确格式化,反斜杠被吞掉了(markdown 就是这样糟糕)。 - Chris Morgan
дёәд»Җд№ҲдҪ дҪҝз”Ё[\w\s]+иҖҢдёҚжҳҜд»–дҪҝз”Ёзҡ„.*?пјҹеңЁжҲ‘зңӢжқҘпјҢ.*?жӣҙеҸҜиғҪжҳҜд»–жғіиҰҒзҡ„пјҢ[\w\s]еӨӘиҝҮдәҺйҷҗеҲ¶дәҶгҖӮ - Chris Morgan
限制是有意为之的。我使用 [\w\s]+,因为显然提问者想要提取很少包含数字的名称。还请注意,提问者想要提取单词,而不是数字。这只是我的个人意见,如有错误请指正。 - pram
2
对于带有重音等有趣特征的名称怎么办?not re.match('\w', u'é')。如果名称是任意的,你不应该排除非拉丁字母名称的可能性。 - Chris Morgan

2

使用这个模式:

pattern = '\[P\].+?\[\/P\]'

这里检查。


这是一个重复的答案(没有添加任何当前顶部答案中没有的内容),而且是不正确的。它会匹配但不会捕获任何内容(没有捕获组)- 它没有回答问题,即使用re.findall获取匹配文本。 - LightCC

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