2

次の時点で理解できない次の正規表現(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}

交替パターンがよくわからないような?

4

3 に答える 3

2

をキャプチャするには、非キャプチャグループをキャプチャグループに変える${...}ために削除する必要があります。名前を付けることもできます。また、[_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オプション (およびgすべての一致を表示する regex101.com のオプション、Python ではfindallorを使用finditer) を使用する必要があります。

非キャプチャ グループの詳細については、SO およびregular-expressions.infoを参照してください。

finditerPython ですべての一致を取得するには、次のように使用できます。

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 デモを見る

于 2015-05-05T11:20:18.560 に答える
1

あなたのパターンはうまく機能します。必要なのは、それを使用して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 ((グローバル調査も実行する)の問題は、パターンにキャプチャ グループがある場合、結果にはキャプチャ グループの内容のリストのみが含まれ、一致結果全体が含まれないことです。したがって、提案されているようにすべてをキャプチャ グループに含めます。ストリビジェフによってfindall) との方法であることができます。

于 2015-05-05T11:30:15.637 に答える
0

gregex101.com ですべての一致を取得するには、修飾子を追加する必要があります

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

于 2015-05-05T11:17:09.997 に答える