re.searchとre.matchの違いは何ですか?
質問
match()
関数の違いは何ですかlibrary / re.html "rel =" noreferrer "> Python re
モジュール?
ドキュメント(< href = "http://docs.python.org/2/library/re.html?highlight=matching%20searching#search-vs-match" rel = "noreferrer">現在のドキュメント)が、覚えていないようです。私はそれを調べて再学習しなければなりません。誰かが例で明確に答えて、(おそらく)頭に残るように期待しています。または、少なくとも質問を返すのに適した場所があり、再学習にかかる時間が短縮されます。
解決
re.match
は、文字列の先頭に固定されています。これは改行とは関係ないため、パターンで ^
を使用することとは異なります。
re.matchのドキュメントの説明:
で0個以上の文字が 文字列の始まりは正規表現パターンに一致し、 対応する
MatchObject
インスタンス。 文字列がそうでない場合は、None
を返します パターンに一致します。これは 長さゼロの一致とは異なります。注:一致を検索する場合 文字列内の任意の場所で、
search()
を使用します 代わりに。
re.search
は、ドキュメントには次のように記載されています:
文字列をスキャンして、 正規表現がある場所 パターンは一致を生成し、 対応する
MatchObject
インスタンス。 に位置がない場合はNone
を返します 文字列はパターンに一致します。ご了承ください これは、見つけることとは異なります のある時点でのゼロ長の一致 文字列。
文字列の先頭で一致する必要がある場合、または文字列全体を一致させる必要がある場合は、 match
を使用します。速いです。それ以外の場合は、 search
を使用します。
ドキュメントには、 match
と search
(複数行の文字列も含む):
Pythonは2つの異なるプリミティブを提供します 通常に基づく操作 式:
match
は一致をチェックします 文字列の先頭のみ、 一方、search
は一致をチェックします 文字列のどこでも(これが Perlはデフォルトで行います)。
match
はsearch
と異なる場合があることに注意してください 正規表現を使用する場合でも'^'
で始まる:'^'
は一致のみ 文字列の先頭、またはMULTILINE
モードもすぐに 改行の後。 &#8220;match
&#8221; 操作が成功するのは、パターンが 文字列の開始で一致する モードに関係なく、または開始時に オプションのpos
で指定された位置 に関係なく引数 改行がそれに先行します。
さて、これで十分です。いくつかのサンプルコードを見てみましょう:
# example code:
string_with_newlines = """something
someotherthing"""
import re
print re.match('some', string_with_newlines) # matches
print re.match('someother',
string_with_newlines) # won't match
print re.match('^someother', string_with_newlines,
re.MULTILINE) # also won't match
print re.search('someother',
string_with_newlines) # finds something
print re.search('^someother', string_with_newlines,
re.MULTILINE) # also finds something
m = re.compile('thing, re.MULTILINE)
print m.match(string_with_newlines) # no match
print m.match(string_with_newlines, pos=4) # matches
print m.search(string_with_newlines,
re.MULTILINE) # also matches
他のヒント
search
&#8658;文字列内のどこかで何かを見つけ、一致オブジェクトを返します。
match
&#8658;文字列の beginning で何かを見つけ、一致オブジェクトを返します。
re.search
文字列全体でパターンを検索しますが、 re.match
は >パターンを検索しない。一致しない場合、文字列の先頭で一致する以外に選択肢はありません。
re.matchおよびre.searchの動作を理解するには、以下の例を参照できます
a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)
re.matchはnoneを返しますが、re.searchはabcを返します。
違いは、 re.match()
は、 Perl 、 grep 、または sed 正規表現の一致。 re.search()
は一致しません。:-)
もっと落ち着いて、ジョンD.クックの発言、 re.match( )
&quot;すべてのパターンに^が付加されているかのように動作します&quot;つまり、 re.match( 'pattern')
は re.search( '^ pattern')
と等しくなります。したがって、パターンの左側を固定します。ただし、パターンの右側を固定しません: 、終了 $
が必要です。
率直に言って、私は re.match()
を廃止すべきだと思います。保持すべき理由を知りたいと思います。
matchは検索よりもはるかに高速であるため、regex.search(&quot; word&quot;)を実行する代わりにregex.match((。*?)word(。*?))を実行すると、パフォーマンスが大幅に向上します。数百万のサンプルを処理します。
この@ivan_bilanからのコメント上記の受け入れられた回答は、そのようなハックが実際に何かを高速化するかどうかを考えさせてくれたので、実際に何トンのパフォーマンスが得られるかを見てみましょう。
次のテストスイートを準備しました:
import random
import re
import string
import time
LENGTH = 10
LIST_SIZE = 1000000
def generate_word():
word = [random.choice(string.ascii_lowercase) for _ in range(LENGTH)]
word = ''.join(word)
return word
wordlist = [generate_word() for _ in range(LIST_SIZE)]
start = time.time()
[re.search('python', word) for word in wordlist]
print('search:', time.time() - start)
start = time.time()
[re.match('(.*?)python(.*?)', word) for word in wordlist]
print('match:', time.time() - start)
10個の測定(1M、2M、...、10Mワード)を行った結果、次のプロットが得られました。
結果として得られる線は、驚くほど(実際にはそれほど驚くほどではない)まっすぐです。そして、この特定のパターンの組み合わせを考えると、 search
関数は(わずかに)高速です。このテストのモラル:コードを過剰に最適化しないでください。
re.matchは、パターンの一致を文字列の先頭で試みます。 re.searchは、一致が見つかるまで文字列全体でパターンの一致を試みます。
はるかに短い:
-
search
は、文字列全体をスキャンします。 -
match
文字列の先頭のみを実行します。
次の例によると:
>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc