Python re.sub的行为与re.findall不同

时间:2017-08-08 01:52:11

标签: python

我很难过。我正在编写Python 3.6.2,使用PyCharm作为我的IDE。以下脚本片段说明了我的问题:

def dosubst(m):
    return m.group() + "X"

line = r"set @message = formatmessage('%s %s', @arg1, @arg2);"
m = re.findall(r"@\w+\b", line, re.IGNORECASE)
print(m[0])  # prints "@message"
print(m[1])  # prints "@arg1"
print(m[2])  # prints "@arg2"

foo = re.sub(r"@\w+\b", dosubst, line, re.IGNORECASE)
print(foo)  # prints "set @messageX = formatmessage('%s %s', @arg1X, @arg2);"

您可以看到re.findall找到三个匹配项。但是,re.sub仅调用dosubst函数两次。如果我将@message更改为message,则re.sub仍会拨打dosubst两次,但会选择@arg1@arg2。百思不得其解。我认为它可能是贪婪的,而不是等待的,但是 - 将@message改为message并且由此产生的行为否定了这一点。谁能解释一下?我正在尝试对SQL进行一些基本的文本解析,以重构大量文件的消息格式。我使用regexr.com来创建我所做的大部分正则表达式的原型,并且它还在行中找到了三次出现的模式。感谢。

2 个答案:

答案 0 :(得分:6)

the documentationre.sub的第四个参数是count,而不是flags。由于re.IGNORECASE碰巧是2,你告诉它只做两次替换。而是通过关键字传递flags

>>> re.sub(r"@\w+\b", dosubst, line, flags=re.IGNORECASE)
"set @messageX = formatmessage('%s %s', @arg1X, @arg2X);"

答案 1 :(得分:0)

通过给出第四个参数count=0。如果你把其他正数代替0而不是它将替换字符串完全相同的时间。

foo = re.sub(r"@\w+\b", dosubst, line, 0, re.IGNORECASE)
print(foo)

输出:

"set @MessageX = formatmessage('%s %s', @arg1X, @arg2X);"