re.search和re.match的区别是什么?

在Python的re模块中,search()match()函数有什么区别?

我读过Python 2文档 (Python 3文档),但我似乎不记得了。我得不停地查资料,重新学习。我希望有人能用例子清楚地回答这个问题,这样(也许)我就能记住它了。或者至少我可以有一个更好的地方带着我的问题回来,重新学习的时间也会更少。

386688 次浏览

re.match锚定在字符串的开头。这与换行符无关,因此它与在模式中使用^是不同的。

正如re.match文档所说:

如果字符串中有零个或多个字符 字符串的开头匹配正则表达式模式,返回 对应MatchObject实例。 如果不是,则返回None 匹配模式;注意这是

注:如果你想找到一个匹配 字符串中的任意位置,使用search() 相反。< / p >

re.search搜索整个字符串,如文档上说:

扫描字符串寻找一个 正则表达式所在的位置 模式生成匹配,并返回 对应MatchObject实例。 对象中没有位置,返回None 字符串匹配模式;请注意, 这和求 中的某个点上的零长度匹配 字符串。< / p >

所以如果你需要匹配字符串的开头,或者匹配整个字符串,请使用match。它更快。否则使用search

文档中有一个#EYZ0 vs. search的特定部分,它也涵盖了多行字符串:

Python提供了两种不同的原语 基于常规的操作 表达式:match检查匹配 只是在一开始search检查匹配 在任何地方在字符串(这是什么

注意match可能不同于search 即使在使用正则表达式时也是如此 '^'开头:只匹配'^' 在字符串的开头,或者在 MULTILINE模式也立即 换行符之后。“# EYZ0” 操作成功仅当模式 匹配字符串开始 不管模态,还是在开始的时候 由可选的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

re.match尝试匹配在字符串的开头模式。re.search尝试匹配模式贯穿整个字符串,直到找到匹配。

re.search 搜索es为贯穿整个字符串模式,而re.match没有搜索模式;如果没有,它没有其他选择,只能在字符串的开头匹配它。

# EYZ0 ⇒在字符串中任意位置查找内容并返回匹配对象。

# EYZ0 ⇒在字符串的开始处找到一些东西,并返回一个匹配对象。

您可以参考下面的示例来了解re.match和re.search的工作原理

a = "123abc"
t = re.match("[a-z]+",a)
t = re.search("[a-z]+",a)

re.match返回none,而re.search返回abc

不同的是,#EYZ0会误导任何习惯了Perlgrep,或sed正则表达式匹配的人,而re.search()则不是。:-)

更严肃地说,正如约翰·d·库克所说re.match()“表现得好像每个模式都有^。”换句话说,re.match('pattern')等于re.search('^pattern')。所以它锚定了图案的左侧。但是不会锚定模式的右侧:仍然需要终止$

坦率地说,鉴于上述情况,我认为re.match()应该被弃用。我很想知道保留它的原因。

匹配比搜索快得多,所以如果要处理数百万个样本,可以使用regex.match((.*?)word(.*?))而不是使用regex.search("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,…), 1000万字),这给了我以下的情节:

match vs. search regex speedtest line plot .

如你所见,搜索'python'模式更快比匹配模式'(.*?)python(.*?)'

Python很聪明。不要试图变得更聪明。

更短:

  • search扫描整个字符串。

  • match只扫描字符串的开头。

以下是前任说的:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc

迅速的回答

re.search('test', ' test')      # returns a Truthy match object (because the search starts from any index)


re.match('test', ' test')       # returns None (because the search start from 0 index)
re.match('test', 'test')        # returns a Truthy match object (match at 0 index)