【问题标题】:Why doesn't ignorecase flag (re.I) work in re.sub() [duplicate]为什么忽略大小写标志(re.I)在re.sub()中不起作用[重复]
【发布时间】:2012-02-07 10:54:19
【问题描述】:

来自 pydoc:

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

示例代码:

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

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

文档没有提到任何关于这个限制的内容,所以我认为我可能做错了什么。

这是什么情况?

【问题讨论】:

    标签: python regex


    【解决方案1】:

    在我看来你应该这样做:

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

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

    【讨论】:

    • 啊,你是对的。我错过了论证要求。我习惯于在字符串对象之后放置标志,就像在 main re.函数,所以我没有过多关注参数调用。谢谢
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      请注意那些仍在处理 Python 2.6.x 安装或更旧版本的人。 Python documentation for 2.6 re 说:

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

      这意味着您不能将标志直接传递给 sub。它们只能与 compile 一起使用:

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

      【讨论】:

        【解决方案4】:

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

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

        (*是禁止指定count,flags作为位置参数。_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'
        >>> 
        

        【讨论】:

          【解决方案5】:

          只是为了补充 Seppo 的答案。根据http://docs.python.org/2.6/library/re.html,仍然有一种方法可以将标志直接传递给 2.6 中的“sub”,如果您必须制作一个包含许多与 2.6 兼容的 2.7 代码,这可能会很有用。引用手册:

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

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

          实际上,这意味着

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

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

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-12-10
            • 2013-03-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-12
            • 1970-01-01
            • 2018-05-31
            相关资源
            最近更新 更多