[英]Difference between re.findall() and re.finditer() when using groups in regex?
考虑以下字符串
text2 = '''
Mr. Schafer
Mr Smith
Ms Davis
Mrs. Robinson
Mr. T
'''
我希望正则表达式匹配完整的名称,如“先生”。 Schafer'例如
使用查找器():
matches = re.finditer(r'(Mr|Ms|Mrs)\.?\s[A-Z]\w*', text2)
for match in matches:
print(match)
结果:
<_sre.SRE_Match object; span=(1, 12), match='Mr. Schafer'>
<_sre.SRE_Match object; span=(13, 21), match='Mr Smith'>
<_sre.SRE_Match object; span=(22, 30), match='Ms Davis'>
<_sre.SRE_Match object; span=(31, 44), match='Mrs. Robinson'>
<_sre.SRE_Match object; span=(45, 50), match='Mr. T'>
finditer() 给了我想要的结果,但不在列表中。
但是当我使用 findall() 时:
re.findall(r'(Mr|Ms|Mrs)\.?\s[A-Z]\w*', text2)
结果:
['Mr', 'Mr', 'Ms', 'Mrs', 'Mr']
为什么是这样? 如何使用 findall() 获得我想要的结果
我想要这个结果:
['Mr. Schafer', 'Mr Smith', 'Ms Davis', 'Mrs. Robinson', 'Mr. T']
re.findall
返回的列表包含:
捕获是用括号括起来的正则表达式的一部分,除非您使用(?:...)
; ?:
在此上下文中告诉 Python 的正则表达式库不要将括号视为定义捕获。 (当然它仍然用于分组。)
所以最简单(也可能是最快)的解决方案是确保正则表达式没有捕获,通过使用(?:...)
来包围标题,而不仅仅是(...)
:
>>> re.findall(r'(?:Mr|Ms|Mrs)\.?\s[A-Z]\w*', text2)
['Mr. Schafer', 'Mr Smith', 'Ms Davis', 'Mrs. Robinson', 'Mr. T']
您还可以明确捕获完整名称:
>>> re.findall(r'((?:Mr|Ms|Mrs)\.?\s[A-Z]\w*)', text2)
['Mr. Schafer', 'Mr Smith', 'Ms Davis', 'Mrs. Robinson', 'Mr. T']
在这种情况下这样做没有多大意义,但是如果您希望模式的一部分不显示在输出中,则“一次捕获”形式可能很有用。
最后,您可能需要元组中的敬语和姓氏:
>>> re.findall(r'(?:(Mr|Ms|Mrs)\.?\s([A-Z]\w*))', text2)
[('Mr', 'Schafer'), ('Mr', 'Smith'), ('Ms', 'Davis'), ('Mrs', 'Robinson'), ('Mr', 'T')]
“()”部分是捕获指示符。
添加“?:”以设置非捕获。
import re
text2 = '''
Mr. Schafer
Mr Smith
Ms Davis
Mrs. Robinson
Mr. T
'''
print(re.findall(r"(?:Mr|Ms|Mrs)\.?\s[A-Za-z]*w*", text2))
# ['Mr. Schafer', 'Mr Smith', 'Ms Davis', 'Mrs. Robinson', 'Mr. T']
https://regexr.com/左侧有一个备忘单。
我更喜欢finditer
不是findall
。 finditer
返回文本中匹配对象的迭代器,而findall
返回文本中匹配模式的列表。 对于有效性,生成器比列出所有读取数据到内存中的列表要好,而层则没有。 要从iterator
获取值,只需使用.group()
。
import re
text2 = '''
Mr. Schafer
Mr Smith
Ms Davis
Mrs. Robinson
Mr. T
'''
matches = re.finditer(r'(Mr|Ms|Mrs)\.?\s[A-Z]\w*', text2)
match_list = [match.group() for match in matches]
print(match_list)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.