web-dev-qa-db-ja.com

正規表現と重複する一致を見つける方法は?

>>> match = re.findall(r'\w\w', 'hello')
>>> print match
['he', 'll']

\ w\wは2文字を意味するため、「he」と「ll」が必要です。しかし、なぜ 'el'と 'lo' notは正規表現に一致するのでしょうか?

>>> match1 = re.findall(r'el', 'hello')
>>> print match1
['el']
>>>
61
futurenext110

findallは、デフォルトでは重複する一致を生成しません。ただし、この式は次のことを行います。

_>>> re.findall(r'(?=(\w\w))', 'hello')
['he', 'el', 'll', 'lo']
_

ここで_(?=...)_は lookahead assertion です:

_(?=...)_は次に_..._が一致する場合に一致しますが、文字列を消費しません。これは先読みアサーションと呼ばれます。たとえば、Isaac (?=Asimov)は、その後に_'Isaac '_が続く場合にのみ_'Asimov'_と一致します。

90

new Python regex module ]を使用できます。これは、一致の重複をサポートします。

>>> import regex as re
>>> match = re.findall(r'\w\w', 'hello', overlapped=True)
>>> print match
['he', 'el', 'll', 'lo']
31
David C

長さゼロのアサーションを除き、入力の文字は常にマッチングで消費されます。入力文字列の特定の文字を何度もキャプチャしたい場合は、正規表現で長さゼロのアサーションが必要になります。

長さゼロのアサーションがいくつかあります(例:^(入力/行の開始)、$(入力/行の終わり)、\b(単語の境界))、ただしルックアラウンド((?<=)肯定的な後読みと(?=)正の先読み)は、入力から重複するテキストをキャプチャできる唯一の方法です。負のルックアラウンド((?<!)負の後読み、(?!)負の先読み)は、ここではあまり役に立ちません。それらがtrueをアサートすると、内部のキャプチャは失敗します。それらが偽を主張する場合、一致は失敗します。これらのアサーションは長さがゼロです(前述のとおり)。つまり、入力文字列の文字を消費せずにアサートします。アサーションに合格すると、実際には空の文字列に一致します。

上記の知識を適用すると、あなたのケースで機能する正規表現は次のようになります。

(?=(\w\w))
10
nhahtdh

正規表現の専門家ではありませんが、同様の 質問 に答えたいと思います。

先読みでキャプチャグループを使用する場合:

正規表現の例:(\ d)(?=。\ 1)

文字列:5252

これは最初の5と最初の2に一致します

(\ d)はキャプチャグループを作成し、(?=\d\1)は文字列を消費せずにキャプチャグループ1が続く任意の数字と一致するため、重複を許可します

0