【问题标题】:Pandas .str.replace and case insensitivityPandas .str.replace 和不区分大小写
【发布时间】:2019-05-20 16:41:47
【问题描述】:

使替换不区分大小写在以下示例中似乎没有效果(我想将 jr.Jr. 替换为 jr em>):

In [0]: pd.Series('Jr. eng').str.replace('jr.', 'jr', regex=False, case=False)
Out[0]: 0    Jr. eng

为什么?我误会了什么?

【问题讨论】:

    标签: python regex string pandas replace


    【解决方案1】:

    case 参数实际上是一种方便的替代指定 flags=re.IGNORECASE 的方法。如果替换不是基于正则表达式的,则它与替换无关。

    所以,当regex=True,这些是你可能的选择:

    pd.Series('Jr. eng').str.replace(r'jr\.', 'jr', regex=True, case=False)
    # pd.Series('Jr. eng').str.replace(r'jr\.', 'jr', case=False)
    
    0    jr eng
    dtype: object
    

    或者,

    pd.Series('Jr. eng').str.replace(r'jr\.', 'jr', regex=True, flags=re.IGNORECASE)
    # pd.Series('Jr. eng').str.replace(r'jr\.', 'jr', flags=re.IGNORECASE)
    
    0    jr eng
    dtype: object
    

    您还可以通过将不区分大小写标志作为?i 的一部分合并到模式中来变得厚颜无耻并绕过两个关键字参数。见

    pd.Series('Jr. eng').str.replace(r'(?i)jr\.', 'jr')
    0    jr eng
    dtype: object
    

    注意
    您需要在正则表达式模式下转义句点 \.,因为 未转义的点是具有不同含义的元字符(匹配 任何字符)。如果要动态转义模式中的元字符,可以使用re.escape

    有关标志和锚点的更多信息,请参阅 this section of the docsre HOWTO


    source code 可以清楚地看出,如果regex=False,则忽略“case”参数。见

    # Check whether repl is valid (GH 13438, GH 15055)
    if not (is_string_like(repl) or callable(repl)):
        raise TypeError("repl must be a string or callable")
    
    is_compiled_re = is_re(pat)
    if regex:
        if is_compiled_re:
            if (case is not None) or (flags != 0):
                raise ValueError("case and flags cannot be set"
                                 " when pat is a compiled regex")
        else:
            # not a compiled regex
            # set default case
            if case is None:
                case = True
    
            # add case flag, if provided
            if case is False:
                flags |= re.IGNORECASE
        if is_compiled_re or len(pat) > 1 or flags or callable(repl):
            n = n if n >= 0 else 0
            compiled = re.compile(pat, flags=flags)
            f = lambda x: compiled.sub(repl=repl, string=x, count=n)
        else:
            f = lambda x: x.replace(pat, repl, n)
    

    您可以看到case 参数仅在if 语句内进行检查。

    IOW,唯一的方法是确保regex=True 以便替换是基于正则表达式的。

    【讨论】:

    • 如果您要打开正则表达式模式,您可能应该转义 .
    • 谢谢!逃避的需要。是我禁用正则表达式的真正原因(我只是懒惰)。
    • @Toby 如果您不想自己转义,可以使用re.escape(mypattern) 转义所有正则表达式元字符。懒惰 FTW!
    猜你喜欢
    • 2015-06-28
    • 2013-03-06
    • 2020-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 2012-12-01
    相关资源
    最近更新 更多