为什么第一个交替不匹配?

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

上的所有匹配项

https://www.regex101.com/r/nP8pK0/1

为了捕获 ${...},您需要删除 ?: 以将 非捕获 组变为 捕获 一个。您也可以为它们命名。此外 [_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 中,您将使用 findallfinditer).

有关 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)]

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": %s\n' % (m.group('named'))

findall (也执行全局研究) 的问题是当您在模式中有捕获组时,结果仅包含一个列表捕获组内容,不再是整个匹配结果。因此,按照 stribizhev 的建议,将所有内容包含在捕获组中可能是 findall).

的一种方式