最初に一致する正規表現で文字列を返す


91

正規表現の最初の一致を取得したい。

この場合、私はリストを取得しました:

text = 'aa33bbb44'
re.findall('\d+',text)

['33'、 '44']

リストの最初の要素を抽出できます。

text = 'aa33bbb44'
re.findall('\d+',text)[0]

'33'

ただし、これは少なくとも1つの一致がある場合にのみ機能します。そうでない場合、エラーが発生します。

text = 'aazzzbbb'
re.findall('\d+',text)[0]

IndexError:リストインデックスが範囲外です

その場合、関数を定義できます。

def return_first_match(text):
    try:
        result = re.findall('\d+',text)[0]
    except Exception, IndexError:
        result = ''
    return result

新しい関数を定義せずにその結果を取得する方法はありますか?


私にとって、受け入れられた答えはうまくいきませんでした。配列インデックスへのアクセスを削除し、len(re.findAll)==0代わりにチェックを使用する必要がありました。
ヴィシャル

回答:


109

次を''追加することで、デフォルトを正規表現に埋め込むことができます|$

>>> re.findall('\d+|$', 'aa33bbb44')[0]
'33'
>>> re.findall('\d+|$', 'aazzzbbb')[0]
''
>>> re.findall('\d+|$', '')[0]
''

re.search他の人から指摘されたものでも動作します:

>>> re.search('\d+|$', 'aa33bbb44').group()
'33'
>>> re.search('\d+|$', 'aazzzbbb').group()
''
>>> re.search('\d+|$', '').group()
''

すばらしいです。search/ .groupはfindall / [0]よりも優れていますか?
ルイスラモンラミレスロドリゲス

6
@LuisRamonRamirezRodriguez一致するものが見つかるとすぐに停止でき、残りのテキストを処理する必要も、すべての一致を保存する必要もありません。したがって、より効率的です。また、@ TimPetersが言ったように、それは文字通り「あなたが望むものです」。あなたや他の誰かがそれを読んで「なぜfindall使われたのか」と疑問に思うとき、それは利点かもしれません。
Stefan Pochmann 2016

43

最初の一致のみが必要な場合は、次のre.search代わりに使用しますre.findall

>>> m = re.search('\d+', 'aa33bbb44')
>>> m.group()
'33'
>>> m = re.search('\d+', 'aazzzbbb')
>>> m.group()
Traceback (most recent call last):
  File "<pyshell#281>", line 1, in <module>
    m.group()
AttributeError: 'NoneType' object has no attribute 'group'

次に、次のmようにチェック条件として使用できます。

>>> m = re.search('\d+', 'aa33bbb44')
>>> if m:
        print('First number found = {}'.format(m.group()))
    else:
        print('Not Found')


First number found = 33

13

私は一緒に行きます:

r = re.search("\d+", ch)
result = return r.group(0) if r else ""

re.searchとにかく文字列の最初の一致のみを検索するので、を使用するよりも意図が少し明確になると思いますfindall


9

あなたはまったく使用すべきではありません.findall()-.search()あなたが望むものです。左端の一致を見つけます。これは必要なものです(またはNone一致が存在しない場合は戻ります)。

m = re.search(pattern, text)
result = m.group(0) if m else ""

それを関数に入れたいかどうかはあなた次第です。一致するものが見つからない場合に空の文字列を返したいのは珍しいことです。そのため、そのようなものは組み込まれていません。.search()一致するものがそれ自体で見つかるかどうか(見つからNoneなかった場合は返されるか、SRE_Matchオブジェクトか)について混乱することはありません。もしそうなら)。


3

できるよ:

x = re.findall('\d+', text)
result = x[0] if len(x) > 0 else ''

あなたの質問は正規表現に正確に関連しているわけではないことに注意してください。むしろ、配列に要素がない場合、どのようにして安全に配列から要素を見つけるのですか。


2
ここでは、「len(x)> 0」を単に「x」に置き換えます。
ウルフアスラク2016

1

コストが高いことを除いて、大量の入力データに必要な部分が含まれていない場合、これは少しパフォーマンスが向上する可能性があります。

def return_first_match(text):
    result = re.findall('\d+',text)
    result = result[0] if result else ""
    return result
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.