624

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

我已阅读文档当前文档),但我似乎从未记得它。我一直不得不查找并重新学习它。我希望有人会用例子清楚地回答它,以便(也许)它会留在我的脑海中。或者至少我会有一个更好的地方来回答我的问题,并且重新学习它需要更少的时间。

4

8 回答 8

603

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

正如re.match 文档所说:

如果字符串开头的零个或多个字符 与正则表达式模式匹配,则返回相应的MatchObject实例。None如果字符串与模式不匹配则返回;请注意,这与零长度匹配不同。

注意:如果要在字符串中的任何位置找到匹配项,请search() 改用。

re.search如文档所述,搜索整个字符串:

扫描字符串以查找正则表达式模式产生匹配的位置,并返回相应的MatchObject实例。None如果字符串中没有位置与模式匹配,则返回;请注意,这与在字符串中的某个点找到零长度匹配不同。

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

该文档有一个针对vs.的特定部分,matchsearch其中也涵盖了多行字符串:

Python 基于正则表达式提供了两种不同的原始操作:仅在字符串的开头match检查 匹配,而在字符串中的任何位置检查匹配 (这是 Perl 默认所做的)。search

请注意, 即使使用以:开头的正则表达式match也可能有所不同,仅匹配字符串的开头,或者在 模式下也紧跟换行符。“<code>match”操作只有在模式匹配字符串的开头( 无论模式如何)或在可选 参数给出的起始位置(无论是否有换行符之前)匹配时才会成功。search'^''^'MULTILINEpos

现在,足够的谈话。是时候看一些示例代码了:

# 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
于 2008-10-08T00:53:12.117 回答
125

search⇒ 在字符串中的任何地方找到一些东西并返回一个匹配对象。

match⇒ 在字符串的开头找到一些东西并返回一个匹配对象。

于 2011-12-31T12:05:43.113 回答
72

match 比 search 快得多,因此如果您使用数百万个数据,您可以执行 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、...、10M 字),结果如下:

匹配与搜索正则表达式 speedtest 线图

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

Python 很聪明。避免试图变得更聪明。

于 2018-04-07T19:03:18.807 回答
57

re.search 整个字符串中搜索模式,re.match而不搜索模式;如果没有,除了在字符串的开头匹配它之外别无选择。

于 2008-10-08T01:07:26.490 回答
38

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

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

re.match会回来none,但re.search会回来abc

于 2015-07-30T05:27:27.010 回答
35

不同之处在于,会re.match()误导任何习惯于Perlgrepsed正则表达式匹配的人,而re.search()不会。:-)

更清醒的是,正如 John D. Cook 所说re.match()“表现得好像每个模式都有 ^ 前缀。” 换句话说,re.match('pattern')等于re.search('^pattern')。所以它锚定了图案的左侧。但它也不会锚定模式的右侧:仍然需要终止$.

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

于 2016-05-21T13:28:47.277 回答
17

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

于 2008-10-08T00:54:57.620 回答
17

矮得多:

  • search扫描整个字符串。

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

跟随前任说:

>>> a = "123abc"
>>> re.match("[a-z]+",a)
None
>>> re.search("[a-z]+",a)
abc
于 2018-10-31T00:22:53.193 回答