我尝试使用?
量词来匹配模式,只有它存在,但我无法按照我的意愿使用它。在下面的示例中,我尝试在AZA
和ZZZ
之后提取一对数字,其中ZZZ
始终显示,但AZA
是可选的。如果缺少AZA
,我只想返回('', [zzz-value])
对(空字符串而不是AZA
值):
输入:
AZA:00zx---
ZZZ:32fd---
testxfiler
gsdkfklsd
fdsfsk
AZA:06x---
ZZZ:50----
gsdkfklsd
gsdkfklsd
fdsfsk
fdsfsk
gsdkfklsd
fdsfsk
ZZZ:32zzz----
fdsfsk
fdsfsk
gsdkfklsd
fdsfsk
AZA:46----
ZZZ:53---
期望的输出:
[(00,32), (06, 50), ('',32), (46,53)]
我的尝试:
re.findall('(?:AZA:([0-9]*))?.*?ZZZ:([0-9]*)', text, re.DOTALL)
我的输出:
[('00', '32'), ('', '50'), ('', '32'), ('', '53')
答案 0 :(得分:3)
(?:AZA:(\d+).*?)?ZZZ:(\d+)
请参阅demo
import re
p = re.compile(ur'(?:AZA:(\d+).*?)?ZZZ:(\d+)', re.DOTALL)
test_str = u"AZA:00zx---\nZZZ:32fd---\ntestxfiler\ngsdkfklsd\nfdsfsk\nAZA:06x---\nZZZ:50----\ngsdkfklsd\ngsdkfklsd\nfdsfsk\nfdsfsk\ngsdkfklsd\nfdsfsk\nZZZ:32zzz----\nfdsfsk\nfdsfsk\ngsdkfklsd\nfdsfsk\nAZA:46----\nZZZ:53---"
re.findall(p, test_str)
答案 1 :(得分:1)
您不需要添加DOTALL修饰符
>>> text = """AZA:00zx---
ZZZ:32fd---
testxfiler
gsdkfklsd
fdsfsk
AZA:06x---
ZZZ:50----
gsdkfklsd
gsdkfklsd
fdsfsk
fdsfsk
gsdkfklsd
fdsfsk
ZZZ:32zzz----
fdsfsk
fdsfsk
gsdkfklsd
fdsfsk
AZA:46----
ZZZ:53---"""
>>> re.findall(r'(?:AZA:([0-9]+)[\S\s]*?)?ZZZ:([0-9]+)', text)
[('00', '32'), ('06', '50'), ('', '32'), ('46', '53')]
[\S\s]*
将匹配任何空格或非空格字符零次或多次。
为什么你的正则表达式无法正常工作?
(?:AZA:([0-9]*))?.*?ZZZ:([0-9]*)
我们都知道在DOTALL模式下,正则表达式中的点也会匹配偶数换行符。因此,通过将(?:AZA:([0-9]*))?
设置为可选,以下.*?
将匹配ZZZ:([0-9]*)
之前存在的所有前面的字符。因此,通过在前面的可选组中包含以下.*?
,AZA:(\d+)
匹配(如果它显示)并且将捕获AZA:
后面的数字。现在,它不会做一场不必要的比赛。
答案 2 :(得分:1)
表单的正则表达式
(?:AZA:(\d+)[^\n]*\n)?(?:ZZZ:)(\d+)[^\n]*
会有所帮助。
例如
>>>re.findall('(?:AZA:(\d+)[^\n]*\n)?(?:ZZZ:)(\d+)[^\n]*' ,x)
[('00', '32'), ('06', '50'), ('', '32'), ('46', '53')]
(?:AZA:(\d+)[^\n]*\n)?
匹配:AZA:
后跟数字\d+
,后跟\n
([^\n]
)以外的任何内容。最后的量词?
确保整个组是可选的。数字在第1组中捕获
(?:ZZZ:)(\d+)[^\n]*
匹配:ZZZ:
后跟数字\d+
以及\n
以外的任何内容。第2组中捕获的数字
您错过了什么
re.findall('(?:AZA:([0-9]*))?.*?ZZZ:([0-9]*)', text, re.DOTALL)
整个(?:AZA:([0-9]*))?.*?
应该是可选的
(?:AZA:([0-9]*))?.*?)?
后跟\n
更改你的正则表达式
re.findall('(?:AZA:([0-9]*).*?)?\nZZZ:([0-9]*)' ,x)
将输出
[('00', '32'), ('06', '50'), ('', '32'), ('46', '53')]