Python 正则表达式 - 了解匹配和搜索之间的区别
Posted
技术标签:
【中文标题】Python 正则表达式 - 了解匹配和搜索之间的区别【英文标题】:Python regex - understanding the difference between match and search 【发布时间】:2012-06-01 17:43:50 【问题描述】:据我所知,
match
:给定一个字符串 str 和一个模式 pat,match 检查 str 是否与 str 开头的模式匹配。
search
:给定一个字符串 str 和一个模式 pat,搜索检查 str 是否与 str 的每个索引中的模式匹配。
如果是这样,在匹配的正则表达式的开头使用'^'
是否有意义?
据我了解,由于match
从一开始就已经检查过了,所以没有。我可能错了;我的错在哪里?
【问题讨论】:
你读过这个吗? docs.python.org/library/re.html#search-vs-match。它解释了一切。 What is the difference between re.search and re.match?的可能重复 【参考方案1】:当具体调用函数re.match
时,^
字符确实没有什么意义,因为该函数在行首开始匹配过程。但是,对于 re 模块中的其他函数,以及在 已编译 正则表达式对象上调用 match 时,它确实有意义。
例如:
text = """\
Mares eat oats
and does eat oats
"""
print re.findall('^(\w+)', text, re.MULTILINE)
打印出来:
['Mares', 'and']
启用re.findall()
和re.MULTILINE
后,它会在文本的每一行为您提供第一个单词(没有前导空格)。
如果做一些更复杂的事情,比如用正则表达式进行词法分析,并将它应该开始匹配的文本中的起始位置传递给编译的正则表达式,它可能会很有用(您可以选择从上一场比赛)。请参阅RegexObject.match 方法的文档。
以简单的词法分析器/扫描器为例:
text = """\
Mares eat oats
and does eat oats
"""
pattern = r"""
(?P<firstword>^\w+)
|(?P<lastword>\w+$)
|(?P<word>\w+)
|(?P<whitespace>\s+)
|(?P<other>.)
"""
rx = re.compile(pattern, re.MULTILINE | re.VERBOSE)
def scan(text):
pos = 0
m = rx.match(text, pos)
while m:
toktype = m.lastgroup
tokvalue = m.group(toktype)
pos = m.end()
yield toktype, tokvalue
m = rx.match(text, pos)
for tok in scan(text):
print tok
打印出来的
('firstword', 'Mares')
('whitespace', ' ')
('word', 'eat')
('whitespace', ' ')
('lastword', 'oats')
('whitespace', '\n')
('firstword', 'and')
('whitespace', ' ')
('word', 'does')
('whitespace', ' ')
('word', 'eat')
('whitespace', ' ')
('lastword', 'oats')
('whitespace', '\n')
这区分了单词的类型;行首的单词,行尾的单词,以及任何其他单词。
【讨论】:
【参考方案2】:我相信没有用。以下内容复制/粘贴自:http://docs.python.org/library/re.html#search-vs-match
Python 提供了两种不同的基于正则表达式的原始操作:re.match()
仅在字符串的开头检查匹配,而re.search()
在字符串中的任何位置检查匹配(这是 Perl 默认所做的) .
例如:
>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<_sre.SRE_Match object at ...>
以'^'
开头的正则表达式可以与search()
一起使用来限制字符串开头的匹配:
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<_sre.SRE_Match object at ...>
但请注意,在 MULTILINE 模式下,match()
仅匹配字符串的开头,而使用带有以 '^'
开头的正则表达式的 search()
将匹配每行的开头。
>>> re.match('X', 'A\nB\nX', re.MULTILINE) # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE) # Match
<_sre.SRE_Match object at ...>
【讨论】:
所以 ^ 在匹配正则表达式的开头是没有意义的吗? 好吧,符号本身可以用于其他用途,例如在[^\w]
中,但我看不出它在检查开始方面有什么用处。【参考方案3】:
在普通模式下,如果您使用匹配,则不需要 ^。
但在多行模式下(re.MULTILINE
),它会很有用,因为 ^ 不仅可以匹配整个字符串的开头,还可以匹配每一行的开头。
【讨论】:
所以 re.MULTILINE 在开始时没有 ^ 就没有意义? @user1413824 似乎是这样,除了$
也受到影响。根据 Python 文档,re.MULTILINE
所做的只是改变 ^
和 $
的含义以上是关于Python 正则表达式 - 了解匹配和搜索之间的区别的主要内容,如果未能解决你的问题,请参考以下文章
通过Python中的正则表达式优化在两个列表之间查找匹配子字符串
Python: 字符串搜索和匹配,re.compile() 编译正则表达式字符串,然后使用match() , findall() 或者finditer() 等方法