【问题标题】:Regex: How do I capture a group after an optional capturing group using regular expressions?正则表达式:如何使用正则表达式在可选捕获组之后捕获组?
【发布时间】:2013-11-28 15:18:52
【问题描述】:

假设我有以下字符串:

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,s3s6 可以。

需要进行一些修改才能产生所需的输出:如果存在则获取M,如果存在括号则获取括号的内容。

【问题讨论】:

    标签: python regex string


    【解决方案1】:

    看来您需要使用非贪婪运算符:

    ^.-(F)([EF]*)(E+)[^FEM]??(M*)(\\(.*\\))?.*?$
    

    请注意,在最后一个.* 的最后一个我添加了一个?。我还将[^FEM]? 更改为[^FEM]??

    在你的第一个样本中,问题是最后一个 .* 吃掉了这个:-) 而你的[^FEM]? 吃掉了这个:( ...因此没有为(\\(.*\\))? 留下任何东西

    (我还删除了单个字母周围的一些方括号,但更多的是有一个更短的正则表达式)

    使用这个正则表达式,我得到以下结果:

    --FE(-)---    ->     'F'    ''     'E'    ''     '(-)'
    --FEM(-)---   ->     'F'    ''     'E'    'M'    '(-)'
    --FEE(--)-    ->     'F'    'E'    'E'    ''     '(--)'
    

    顺便说一句:我还将删除(\\(.*\\))? 末尾的?,因为即使您不将其放在那里,与该部分不匹配的字符串也会被以下.*? 使用。

    【讨论】:

    • 这就是问题所在。左括号由[^FEM]? 使用,其余字符串由结尾.* 使用
    • 这部分有帮助。但是,该表达式不能解决诸如 --FEE-M(--)-- 或 --FEM-(-)- 之类的问题
    • 在我的测试中,使用 --FEE-M(--)-- 的模式产生:'F' 'E' 'E' 'M' '(--)'。那么预期的输出是什么?
    • 很奇怪。对我来说不是。你在用python吗?如果是这样,您是否使用任何标志?对我来说--FEE-M(--)-- 产生'F','E','E','',''
    • 是的,我使用的是 python,没有特殊标志。这就是我所拥有的:m = re.search('^.-(F)([EF]*)(E+)[^FEM]??(M*)(\(.*\)).*?$', '--FEE-M(--)--') print " '%s' '%s' '%s' '%s' '%s' " % (m.group(1), m.group(2), m.group(3), m.group(4), m.group(5))
    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多