python – 正規表現検索とfindall

私は与えられた正規表現の文字列内のすべての一致を見つける必要があります。私が期待したことをしていないケースを見つけるまで、
findall()を使用しています。例えば:

regex = re.compile('(d+,?)+')
s = 'There are 9,000,000 bicycles in Beijing.'

print re.search(regex, s).group(0)
> 9,000,000

print re.findall(regex, s)
> ['000']

この場合、
search()
は必要なものを返します(最長一致)、 findall()
の動作は異なりますが、 docsはそれが同じでなければならないことを意味します:

findall()は最初のパターンだけでなくパターンのすべてのパターンに一致します
   search()のように。

  • その行動はなぜ異なるのですか?

  • findall()(または他のもの)を使って
    search()の結果をどのように達成できますか?

ベストアンサー

さて、私は何が起きているのかを、docsから見ています:

パターンに1つ以上のグループが存在する場合は、グループのリストを返します。
      パターンに複数のグループがある場合、これはタプルのリストになります。

結局のところ、あなたはグループ「( d +
,?)」を持っています…それで、それはこのグループの最後の出現、つまり000です。

1つの解決策は、このように、正規表現全体をグループで囲むことです

regex = re.compile('((d+,?)+)')

[( ‘9000,000’、
‘000’)]を返します。これは、一致する両方のグループを含むタプルです。もちろん、あなたは最初のものだけを気にします。

個人的には、次の正規表現を使用します

regex = re.compile('((d+,)*d+)')

“これは悪い番号9,123です”のようなものと一致するのを避けるために

編集する。

式をカッコで囲むことや、タプルを扱うことを避ける方法があります

s = "..."
regex = re.compile('(d+,?)+')
it = re.finditer(regex, s)

for match in it:
  print match.group(0)

finditerは、見つかったすべての一致にアクセスするために使用できるイテレータを返します。これらの一致オブジェクトはre.searchが返すものと同じです。したがって、group(0)は期待した結果を返します。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です