Python 模块中的函数search()
和match()
函数有什么区别?re
我已经阅读了文档(当前文档),但我似乎永远不会记住它.我不得不查阅并重新学习它.我希望有人会用例子清楚地回答它,以便(也许)它会坚持到底.或者至少我会有一个更好的地方回答我的问题,重新学习它将花费更少的时间.
re.match
锚定在字符串的开头.这与换行符无关,因此与^
在模式中使用不同.
正如re.match文档所说:
如果字符串开头的零个或多个字符 与正则表达式模式匹配,则返回相应的
MatchObject
实例.None
如果字符串与模式不匹配则返回; 请注意,这与零长度匹配不同.注意:如果要在字符串中的任何位置找到匹配项,请
search()
改用.
re.search
搜索整个字符串,如文档所示:
扫描字符串,查找正则表达式模式生成匹配的位置,并返回相应的
MatchObject
实例.None
如果字符串中没有位置与模式匹配则返回; 请注意,这与在字符串中的某个点找到零长度匹配不同.
所以如果你需要在字符串的开头匹配,或者匹配整个字符串使用match
.它更快.否则使用search
.
该文档有一个针对match
vs.search
的特定部分,其中还包含多行字符串:
:python提供基于正则表达式两种不同的基本操作
match
进行匹配检查, 才刚刚开始的字符串,而search
用于匹配检查 任何地方的字符串(这是Perl并默认情况下).请注意, 即使使用以下列开头的正则表达式,
match
也可能有所不同:仅在字符串的search
开头匹配,或者在 紧跟在换行符后的模式中.只有当模式在字符串的开头匹配时, 无论模式如何,或者在可选 参数给出的起始位置,无论新行是否在它之前," "操作都会成功.'^'
'^'
MULTILINE
match
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
⇒在字符串中的任何位置查找并返回匹配对象.
match
⇒ 在字符串的开头找到一些东西并返回一个匹配对象.
re.search
搜索的模式ES 整个字符串,而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,......,10M字)给了我以下图:
由此产生的线条令人惊讶地(实际上并不令人惊讶地)直线.并且考虑到这种特定的模式组合,该search
功能(稍微)更快.这个测试的道德:避免过度优化你的代码.
您可以参考以下示例来了解re.match和re.search的工作情况
a = "123abc" t = re.match("[a-z]+",a) t = re.search("[a-z]+",a)
re.match将不返回任何内容,但re.search将返回abc.
不同的是,re.match()
误导任何习惯于Perl,grep或sed正则表达式匹配的人,而re.search()
不是.:-)
更为清醒的是,正如约翰·D·库克所言,re.match()
"表现得好像每个模式都在前面." 换句话说,re.match('pattern')
等于re.search('^pattern')
.所以它锚定了一个模式的左侧.但它也没有锚定模式的右侧:仍然需要终止$
.
坦率地说,我认为re.match()
应该弃用.我很想知道它应该保留的原因.
re.match尝试匹配字符串开头的模式.re.search尝试在整个字符串中匹配模式,直到找到匹配项.