为什么不忽略标志(re.I)在re.sub()中工作

时间:2012-01-11 02:04:46

标签: python regex

来自pydoc:

  

re.sub = sub(pattern,repl,string,count = 0,flags = 0)
      返回通过替换最左边获得的字符串       由字符串中的模式非重叠出现       替换代表repl可以是字符串也可以是可调用的;       如果处理了一个字符串,则反斜杠转义。如果是       一个可调用的,它传递了匹配对象,必须返回       要使用的替换字符串。

示例代码:

import re
print re.sub('class', 'function', 'Class object', re.I)

除非我将模式更改为“Class”,否则不会进行替换。

文档没有提到有关此限制的任何内容,因此我假设我可能做错了什么。

这是怎么回事?

5 个答案:

答案 0 :(得分:57)

我觉得你应该这样做:

import re
print re.sub('class', 'function', 'Class object', flags=re.I)

如果没有这个,re.I参数将传递给count参数。

答案 1 :(得分:7)

flags参数是第五个 - 你将re.I的值作为count参数传递(一个容易犯的错误)。

答案 2 :(得分:3)

请注意仍然处理Python 2.6.x安装或更早版本的用户。 Python documentation for 2.6 re说:

re.sub(pattern, repl, string[, count])

re.compile(pattern[, flags])

这意味着你不能直接将标志传递给sub。它们只能用于编译:

regex = re.compile('class', re.I)
regex.sub("function", "Class object")

答案 3 :(得分:1)

为避免此类错误,可以使用以下猴子补丁:

import re
re.sub = lambda pattern, repl, string, *, count=0, flags=0, _fun=re.sub: \
    _fun(pattern, repl, string, count=count, flags=flags)

*禁止指定countflags作为位置参数。_fun=re.sub将使用声明时间re.sub。)

演示:

$ python
Python 3.4.2 (default, Oct  8 2014, 10:45:20) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> re.sub(r'\b or \b', ',', 'or x', re.X)
'or x'   # ?!
>>> re.sub = lambda pattern, repl, string, *, count=0, flags=0, _fun=re.sub: \
...     _fun(pattern, repl, string, count=count, flags=flags)
>>> re.sub(r'\b or \b', ',', 'or x', re.X)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes 3 positional arguments but 4 were given
>>> re.sub(r'\b or \b', ',', 'or x', flags=re.X)
', x'
>>> 

答案 4 :(得分:0)

只是为了补充Seppo的答案。根据{{​​3}},仍有一种方法可以将标志直接传递给&#39; sub&#39;在2.6中,如果你必须制作2.7代码,其中很多子代码与2.6兼容,那么这可能很有用。引用手册:

  

...如果需要指定正则表达式标志,则必须使用RE对象,或在模式中使用嵌入式修饰符;例如,sub(&#34;(?i)b +&#34;,&#34; x&#34;,&#34; bbbb BBBB&#34;)返回&#39; x x&#39; < / p>

  

(?iLmsux)(来自集合中的一个或多个字母&#39;我&#39; L&#39;&#39; m&#39;&#39; s&#39; ,&#39; u&#39;,&#39; x&#39;。)该组匹配空字符串;字母设置相应的标志:re.I(忽略大小写),re.L(依赖于语言环境),re.M(多行),re.S(点匹配所有),re.U(取决于Unicode),以及re.X(详细),用于整个正则表达式。 (标志在模块内容中描述。)如果您希望将标志包含在正则表达式的一部分中,而不是将标志参数传递给re.compile()函数,这将非常有用。

实际上,这意味着

print re.sub("class", "function", "Class object", flags= re.IGNORECASE)

可以使用修饰符(?ms)重写为

print re.sub("(?i)class", "function", "Class object")