?不消耗空间

时间:2018-01-02 14:50:39

标签: regex python-3.6

有人可以向我解释为什么一个匹配但两个不匹配?

示例1

>>> a = 'Prompt: \n'
>>> b = re.compile('Prompt:[ \t]?(?!\n)')
>>> re.search(b, a)
<_sre.SRE_Match object; span=(0, 7), match='Prompt:'>

示例2

>>> a = 'Prompt: \n'
>>> b = re.compile('Prompt:[ \t]+(?!\n)')
>>> re.search(b, a)
>>

2 个答案:

答案 0 :(得分:1)

正如其他人所说?使字符串成为可选字符串。第一个模式匹配,因为如果\n跟随它,它实际上不会匹配空格/选项卡。 正则表达式希望匹配某些内容,因此它会尝试模式的每次迭代,直到找到匹配项并确切地回复它。第二种模式是强制匹配至少一个空格字符,这不会给你的正则表达式一个出路

一些正则表达式允许占有量词?+使您的模式变为Prompt:[ \t]?+(?!\n)。不幸的是,python没有,但这可以缓解这个问题。

代码

只需将您的模式更改为以下内容: See regex in use here

Prompt:(?![ \t]*\n)

用法

See code in use here

import re

r = re.compile(r"Prompt:(?![ \t]*\n)")

# Doesn't match because no text between Prompt: and \n
s = 'Prompt: \n'
m = r.search(s)
if m:
    print "m: " + m.group(0)

# Matches because text exists between Prompt: and \n
s2 = 'Prompt: Something\n'
m2 = r.search(s2)
if m2:
    print "m2: " + m2.group(0)

以上输出:m2: Prompt:(这是正确的,因为在换行符之前有Something)。

答案 1 :(得分:0)

您的正则表达式包含一个否定前瞻,它专门拒绝匹配字符串"Prompt: "后跟换行符的任何匹配。

使用[ \t]?,有一种方法可以通过不匹配空间来找到匹配,因此正则表达式引擎选择该方法,如果有方法可以生成匹配,则绝望地寻求返回匹配。使用[ \t]+您无法提供出路,因此无法找到匹配项。

为什么你把断言放在那里并不完全清楚;但删除它肯定允许字符串按预期匹配,显然需要。

这里没有真正重要,但通常的做法是使用原始Python字符串r'...'作为正则表达式。在您的示例中,让Python替换\t使用文字选项卡而\n使用文字换行符很奇怪但技术上无害,因为这些是您想要匹配的实际字符(可能分别不匹配? ?)但是与\s\d等许多其他反向序列完全分开。

要说&#34;可能有空格,但不能用换行符&#34;,尝试类似

re.compile(r'Prompt:(?![ \t]*\n)')

如果您希望空格包含在匹配中,您可以在断言后放置\s*