2017-04-17 9 views
2

I次のPythonの正規表現があります。Pythonの正規表現:のfindAll()と検索()

>>> p = re.compile(r"(\b\w+)\s+\1") 

\b      :   ワード境界
\w+  :   一つ以上の英数字
\s+  :    1つ以上の空白(\t\n、..)
\1      :   グループ1の後方参照(= (..)の間の部分)

この正規表現は、単語の全二重出現箇所を見つける必要 - 2つの出現箇所である場合間に空白を入れてお互いに隣り合っています。 検索機能を使用する場合
正規表現が正常に動作するようです:

>>> p.search("I am in the the car.") 

<_sre.SRE_Match object; span=(8, 15), match='the the'> 

た試合は、私が予想していたと同じように、the theです。奇妙な行動がのfindAll機能である:

>>> p.findall("I am in the the car.") 

['the'] 

た試合は今だけtheです。なぜ違い?

+3

findall'戻っ 'ためだけキャプチャグループ(またはそれ以外は完全一致)。 –

+0

https://docs.python.org/3/library/re.html#re.findall「パターンに1つ以上のグループが含まれている場合は、グループのリストを返してください」 – melpomene

+0

ああ、今すぐ表示されます。ありがとうございました。だから私は問題を解決するために非キャプチャグループを使用する必要がありますか?今すぐ試してみます.. –

答えて

3

正規表現でグループを使用する場合、findall()はグループのみを返します。 documentationから:

If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group.

あなたは後方参照を使用するときにグループの使用を避けることはできませんが、パターン全体の周りに新しいグループを置くことができます。

>>> p = re.compile(r"((\b\w+)\s+\2)") 
>>> p.findall("I am in the the car.") 
[('the the', 'the')] 

外側のグループがグループ1です、逆参照はグループ2を指しているはずです。2つのグループがあるので、エントリごとに2つの結果があります。

>>> p = re.compile(r"((?P<word>\b\w+)\s+(?P=word))") 

は、あなただけの外側のグループ結果にそれを戻ってフィルタリングすることができます::という名前のグループを使用すると、これは読みやすくする可能性のある場合

>>> [m[0] for m in p.findall("I am in the the car.")] 
['the the'] 
+0

素晴らしい答え!ありがとうMartijn :-) –