假设我有以下字符串:
s1=u'--FE(-)---'
s2=u'--FEM(-)---'
s3=u'--FEE(--)-'
我想匹配F,E,E,M和不同组中括号的内容。
我尝试过以下正则表达式:
u'^.-([F])([EF]*)([E]+)[^FEM]?(M*)?(\\(.*\\))?.*$'
此表达式为不同的字符串提供以下组和跨度:
s1 -> 'F',(2,3) , '',(3,3) , 'E',(3,4) , '',(5,5) , None,(-1,-1)
s2 -> 'F',(2,3) , '',(3,3) , 'E',(3,4) , 'M',(4,5) , (-),(5,8)
s3 -> 'F',(2,3) , 'E',(3,4) , 'E',(4,5) , '',(6,6) , None,(-1,-1)
对于s2,我得到了想要的行为,括号内容的匹配,但对于s1和s3,我没有。
如果我没有与包含'M'的组的正确匹配,我如何创建一个与括号内容匹配的正则表达式?
编辑:
DWilches的答案使用正则表达式
解决了初始问题'^.-(F)([EF]*)(E+)[^FEM]??(M*)(\(.*\)).*?$'
但是,括号组也是可选的。以下简短的python脚本澄清了问题:
s1=u'--FE(-)---'
s2=u'--FEM(-)--'
s3=u'--FEE(--)-'
s4=u'--FEE-M(---)--'
s5=u'--FE-M-(-)-'
s6=u'--FEM--'
s7=u'--FE-M--'
ll=[s1,s2,s3,s4,s5,s6,s7]
import re
rr1=re.compile(u'^.-(F)([EF]*)(E+)[^FEM]??(M*)[^FEM]??(\(.*\)).*?$')
rr2=re.compile(u'^.-(F)([EF]*)(E+)[^FEM]??(M*)[^FEM]??(\(.*\))?.*?$')
for s in ll:
b=rr1.search(s)
print s
if b:
print " '%s' '%s' '%s' '%s' '%s' " % (b.group(1), b.group(2), b.group(3), b.group(4), b.group(5))
else:
print 'No match'
print '######'
对于rr1
,输出为:
--FE(-)---
'F' '' 'E' '' '(-)'
######
--FEM(-)--
'F' '' 'E' 'M' '(-)'
######
--FEE(--)-
'F' 'E' 'E' '' '(--)'
######
--FEE-M(---)--
'F' 'E' 'E' 'M' '(---)'
######
--FE-M-(-)-
'F' '' 'E' 'M' '(-)'
######
--FEM--
No match
######
--FE-M--
No match
######
对于前5个字符串是可以的,但不是最后两个字符串,因为它需要括号。
然而,rr2
将?
添加到(\(.*\))
会产生以下输出:
--FE(-)---
'F' '' 'E' '' '(-)'
######
--FEM(-)--
'F' '' 'E' 'M' '(-)'
######
--FEE(--)-
'F' 'E' 'E' '' '(--)'
######
--FEE-M(---)--
'F' 'E' 'E' '' 'None'
######
--FE-M-(-)-
'F' '' 'E' '' 'None'
######
--FEM--
'F' '' 'E' 'M' 'None'
######
--FE-M--
'F' '' 'E' '' 'None'
######
这适用于s1,s2,s3
和s6
。
需要进行一些修改才能产生所需的输出:如果存在,则获取M
;如果括号存在,则获取括号的内容。
答案 0 :(得分:3)
您似乎需要使用非贪婪的运算符:
^.-(F)([EF]*)(E+)[^FEM]??(M*)(\\(.*\\))?.*?$
请注意,在最后一个.*
我添加了?
。我还为[^FEM]?
更改了[^FEM]??
。
在您的第一个示例中,问题是最后.*
正在吃掉这个:-)
当[^FEM]?
正在吃掉它时:(
...因此不会为(\\(.*\\))?
(我还删除了单个字母周围的一些方括号,但更多的是使用较短的正则表达式)
使用此正则表达式,我获得以下结果:
--FE(-)--- -> 'F' '' 'E' '' '(-)'
--FEM(-)--- -> 'F' '' 'E' 'M' '(-)'
--FEE(--)- -> 'F' 'E' 'E' '' '(--)'
顺便说一句:我还会删除?
末尾的(\\(.*\\))?
,因为即使你没有把它放在那里,下面也会使用与该部分不匹配的字符串.*?
。