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-正则表达式

了解 Perl 正则表达式修饰符 /m 和 /s [重复]

Python正则表达式之 - ?: / ?= / ?!

Python-正则表达式

Python: 字符串搜索和匹配,re.compile() 编译正则表达式字符串,然后使用match() , findall() 或者finditer() 等方法