i具有以下正则表达式(python),我在以下几点不明白。为什么它也不匹配第一个交替?
REGEX(间隔以更好地理解):
(?:
${
(?P<braced>
[_a-zA-Z][a-zA-Z0-9]*(?::[_a-zA-Z][_a-zA-Z0-9]*)+
)
}
)
| ### SECOND ALTERNATION ###
(?:
$
(?P<named>
[_a-zA-Z][a-zA-Z0-9]*(?::[_a-zA-Z][_a-zA-Z0-9]*)+
)
)
测试字符串:
asdasd $ asd:sd $ {asd123:asd} $ home $$ asd
匹配的东西:
asdasd $ asd:sd $ {asd123:asd} $ home $ home $$ asd
根据上述正则方式,也应该出现第一个交替,即:
${asd123:asd}
看来我没有得到交替模式?
要捕获 ${...}
,您需要删除 ?:
以将 noncapturing 组变成捕获。您也可以将它们命名。另外 [_ A-ZA-Z0-9] 等于 w ,因此我们可以稍微缩短您的正则是:
(?P<Alternation1>
${(?P<braced>[_a-zA-Z][a-zA-Z0-9]*(?::[_a-zA-Z]w*)+)
}
)
|
(?P<Alternation2>
$(?P<named>[_a-zA-Z][a-zA-Z0-9]*(?::[_a-zA-Z]w*)+
)
)
看看演示。此正则需要使用x
选项(以及Regex101.com上的g
选项以显示所有匹配项,在Python中,您将使用findall
或finditer
)。
有关非捕获组的更多信息,请在so和juropard-expressions.info中获得。
要在Python中获得所有匹配项,您可以这样使用finditer
:
import re
p = re.compile(ur'''(?P<Alternation1>
${(?P<braced>[_a-zA-Z][a-zA-Z0-9]*(?::[_a-zA-Z]w*)+)
}
)
|
(?P<Alternation2>
$(?P<named>[_a-zA-Z][a-zA-Z0-9]*(?::[_a-zA-Z]w*)+
)
)
''', re.VERBOSE)
test_str = u"asdasd $asd:sd + ${asd123:asd} $HOME $$asd"
print [x for x in re.findall(p, test_str)]
请参阅IDEONE DEMO
您的模式效果很好,您所需要的只是与finditer
一起进行全局研究并获得整个匹配:
>>> for m in re.finditer(pattern, text):
... print 'whole match: %s' (m.group(0))
... print 'group "braced": %s' % (m.group('braced'))
... print 'group "named": %sn' % (m.group('named'))
(findall
的问题(也执行全局研究)是,当您在模式中捕获组时,结果仅包含捕获组内容的列表,而整个匹配项不再包含结果。因此,按照 findall
的建议,将所有内容包裹在捕获组中。
您需要添加g
修改器才能在Regex101.com上获取所有匹配项
https://www.regex101.com/r/np8pk0/1