具有多行和d的非reedy行为

2024-06-26 14:46:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有下面的字符串,其中我尝试将对应的'foo'中的字符串与'bar=1'、'bar=2'或'bar=3'匹配。所以一次只能有一场比赛。在

file_header

foo lorem ipsum \pope
24 dolor sit amet, consectetur adipisici elit
Excepteur sint obcaecat cupiditat non 
gnu blu bar=1

foo lorem ipsum \
@>@!@ consectetur adipisici elit
gnu blu bar=2
foo lorem ipsum
23 dolor sit amet, consectetur adipisici elit
gnu blu bar=3

foo ... etc

我尝试了一切,从简单的^foo.*?bar=2$到类似^(?!\bfoo\b.*\bfoo\b).*\bfoo\b.*bar=2$的东西。但是当multiline和dotall激活后,它将始终匹配第一个'foo'甚至标记整个文件头。:(

在使用多行和dotall时,似乎不可能出现非贪婪行为。在


Tags: 字符串gnufoobaripsumloremdoloramet
3条回答

贪婪是从左到右的

它与MULTILINEDOTALL无关,它是非贪婪算子 只影响比赛的结束,不影响比赛的开始。在

要满足您的需求,请在您的模式前面添加.*。在

>>> re.findall(r'.*(foo.*?bar=1)', s, re.DOTALL)
['foo lorem ipsum \\pope\n24 dolor sit amet, consectetur adipisici elit\nExcepteur sint obcaecat cupiditat non \ngnu blu bar=1']
>>> re.findall(r'.*(foo.*?bar=2)', s, re.DOTALL)
['foo lorem ipsum @>@!@ consectetur adipisici elit\ngnu blu bar=2']
>>> re.findall(r'.*(foo.*?bar=3)', s, re.DOTALL)
['foo lorem ipsum\n23 dolor sit amet, consectetur adipisici elit\ngnu blu bar=3']

你可以使用像

^foo(?:(?!^foo|bar=2$).)*bar=2$

(?:(?!^foo|bar=2$).)*匹配不是foo(在一行/字符串的开头)并且不是{}在行/字符串结尾的任何文本。在

参见regex demo。但是,这样的构造是消耗资源的,建议展开它。这里有一个选项:

^{pr2}$

another demo。在

此程序查找foo <stuff> bar=<number>的所有非重叠出现。请注意,在re.MULTILINE-模式下成功地使用了非贪心运算符:^foo.*?bar=\d+$

import re
from pprint import pprint

data = '''
file_header

foo lorem ipsum \pope
24 dolor sit amet, consectetur adipisici elit
Excepteur sint obcaecat cupiditat non 
gnu blu bar=1

foo lorem ipsum \
@>@!@ consectetur adipisici elit
gnu blu bar=2
foo lorem ipsum
23 dolor sit amet, consectetur adipisici elit
gnu blu bar=3
'''

matches = re.findall(r'^foo.*?bar=\d+$', data, re.DOTALL|re.MULTILINE)
pprint (matches)

结果:

^{pr2}$

相关问题 更多 >