Python正则表达式中的可选贪婪组
我正在尝试写一个正则表达式,用来匹配一个字符串,这个字符串可能包含也可能不包含两个标签。我需要这个表达式能根据标签是否存在,返回字符串中的所有五个部分,但当我把标签设为可选时,通配符的部分似乎会把它们都吞掉:
输入可能是:
text{a}more{b}words
{a}text{b}test
text
text{b}text
text{b}
text{a}text
等等。唯一可以保证的是,<a>
标签总是在 <b>
标签之前,如果它们存在的话。
我现在的表达式看起来是这样的:
^(.*?)(\{a\})?(.*?)(\{b\})?(.*?)$
不幸的是,这样做会把所有文本都放进最后一个组里,无论标签是否存在。有没有办法让它们贪婪一些,同时又保持可选呢?可惜 re.findall
似乎也没有帮助。
任何帮助都会非常感谢! :)
5 个回答
0
不太确定这是否能得到你想要的结果,不过:
import re
inputs = ['text{a}more{b}words',
'{a}text{b}test',
'text',
'text{b}text',
'text{b}',
'text{a}text']
pattern = re.compile(r'^([^{]*)(\{a\})?([^{]*)(\{b\})?([^{]*)$')
for inpt in inputs:
match = pattern.match(inpt)
if match:
print match.groups()
0
我找到了一种解决办法,虽然看起来不太好看,但似乎有效:
^((?P<b1>.*)(?P<o1>\{start\})(?P<m1>.*)(?P<c1>\{end\})(?P<e1>.*))|((?P<b2>.*)(?P<c2>\{end\})(?P<e2>.*))|((?P<b3>.*)(?P<o3>\{start\})(?P<e3>.*))$
4
试试下面这个正则表达式:^(.*(?={a})|.*?)({a})?(.*(?={b})|.*)({b})?(.*?)$
import re
inputs = ['{a}text{b}test', 'text', 'text{b}text', 'text{b}', 'text{a}text']
p = re.compile(r"^(.*(?={a})|.*?)({a})?(.*(?={b})|.*)({b})?(.*?)$")
for input in inputs:
print p.match(input).groups()
输出结果:
('', '{a}', 'text', '{b}', 'test')
('', None, 'text', None, '')
('', None, 'text', '{b}', 'text')
('', None, 'text', '{b}', '')
('text', '{a}', 'text', None, '')