Answers:
re.match
锚定在字符串的开头。这与换行无关,因此它与^
在模式中使用的方式不同。
如重新匹配文档所述:
如果字符串开头的零个或多个字符 与正则表达式模式匹配,则返回相应的
MatchObject
实例。None
如果字符串与模式不匹配,则返回;否则返回false。请注意,这与零长度匹配不同。注意:如果要在字符串中的任何位置找到匹配项,请
search()
改用。
re.search
搜索整个字符串,如文档所述:
扫描字符串以查找正则表达式模式产生匹配项的位置,然后返回相应的
MatchObject
实例。None
如果字符串中没有位置与模式匹配,则返回;否则返回false。请注意,这与在字符串中的某个点找到零长度匹配不同。
因此,如果您需要匹配字符串的开头,或者匹配整个字符串,请使用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
match
而不是更通用search
?是为了速度吗?
match
?用非直觉的名称为API播种以迫使我阅读文档是否明智?我还是不会做!反叛!
match
看上去faster
比搜索要好一点,但是根据性能测试,您的示例似乎是错误的:stackoverflow.com/questions/180986/…–
search
⇒在字符串中的任何地方找到东西,然后返回一个匹配对象。
match
⇒ 在字符串的开头找到一些内容,然后返回匹配对象。
re.search
搜索 ES该模式在整个字符串,而re.match
没有搜索不到的格局; 如果没有,则除了在字符串开头匹配外,别无选择。
fullmatch
在phyton 3.4中)?
match比搜索快得多,因此如果不使用regex.search(“ word”),则可以执行regex.match((。*?)word(。*?)),如果您使用数百万个样品。
@ivan_bilan在上面接受的答案下的评论让我开始思考是否有这样的hack是否真的在加速任何事情,所以让我们找出您将真正获得多少性能。
我准备了以下测试套件:
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
功能(略)更快。该测试的实质是:避免过度优化代码。
match
函数仍比该search
函数快。您可以通过与进行比较re.search('^python', word)
来检查脚本re.match('python', word)
(或者re.match('^python', word)
相同,但是如果您不阅读文档并且似乎不影响性能
match
函数通常更快的说法。该match
快的时候,你要搜索开头的字符串时,search
速度更快,当你想要搜索整个字符串。这符合常识。这就是@ivan_bilan错误的原因-他曾经match
在整个字符串中进行搜索。这就是为什么您是对的-您曾经match
在字符串的开头搜索。如果您不同意我的观点,请尝试查找正则表达式,match
因为它比做re.search('python', word)
同样的事情要快。
re.match('python')
是略高于更快re.match('^python')
。它一定要是。
match
如果要在字符串的开头搜索(例如,使用search
function在字符串的开头查找单词),函数会更快一些re.search('^python', word)
。但是我发现这很奇怪,如果您告诉search
函数在字符串的开头进行搜索,它应该和match
函数一样快。
区别在于,re.match()
误导习惯于Perl,grep或sed正则表达式匹配的任何人,并且re.search()
不会。:-)
正如约翰·D·库克(John D. Cook)所说,要更加清醒一些,re.match()
“表现得好像每个模式都以^开头。” 换句话说,re.match('pattern')
等于re.search('^pattern')
。因此,它锚定了图案的左侧。但这也没有固定模式的右侧:仍然需要终止$
。
坦白地说,我认为re.match()
应该弃用。我很想知道应该保留它的原因。