为什么第一个交替不匹配?
why does the first alternation not match?
我有following regular expression (Python) 我在下面的地方不明白。为什么它也不匹配第一个交替?
正则表达式(间隔以便更好地理解):
(?:
$\{
(?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 $$asd
根据上面的正则表达式模式,第一个交替也应该出现,即:
${asd123:asd}
我好像不太明白交替模式?
您需要添加 g
修饰符才能获得 regex101.com
上的所有匹配项
为了捕获 ${...}
,您需要删除 ?:
以将 非捕获 组变为 捕获 一个。您也可以为它们命名。此外 [_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*)+
)
)
看看demo。此正则表达式需要使用 x
选项(以及 regex101.com 上的 g
选项以显示所有匹配项,在 Python 中,您将使用 findall
或 finditer
).
有关 non-capturing groups is available on SO and at regular-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)]
您的模式运行良好,您只需将它与 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": %s\n' % (m.group('named'))
(findall
(也执行全局研究) 的问题是当您在模式中有捕获组时,结果仅包含一个列表捕获组内容,不再是整个匹配结果。因此,按照 stribizhev 的建议,将所有内容包含在捕获组中可能是 findall
).
的一种方式
我有following regular expression (Python) 我在下面的地方不明白。为什么它也不匹配第一个交替?
正则表达式(间隔以便更好地理解):
(?:
$\{
(?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 $$asd
根据上面的正则表达式模式,第一个交替也应该出现,即:
${asd123:asd}
我好像不太明白交替模式?
您需要添加 g
修饰符才能获得 regex101.com
为了捕获 ${...}
,您需要删除 ?:
以将 非捕获 组变为 捕获 一个。您也可以为它们命名。此外 [_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*)+
)
)
看看demo。此正则表达式需要使用 x
选项(以及 regex101.com 上的 g
选项以显示所有匹配项,在 Python 中,您将使用 findall
或 finditer
).
有关 non-capturing groups is available on SO and at regular-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)]
您的模式运行良好,您只需将它与 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": %s\n' % (m.group('named'))
(findall
(也执行全局研究) 的问题是当您在模式中有捕获组时,结果仅包含一个列表捕获组内容,不再是整个匹配结果。因此,按照 stribizhev 的建议,将所有内容包含在捕获组中可能是 findall
).