[英]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.