不区分大小写的替换

Ada*_*nst 160 python string case-insensitive

在Python中进行不区分大小写的字符串替换的最简单方法是什么?

Bla*_*rad 203

string类型不支持此功能.您可能最好使用带有re.IGNORECASE选项的正则表达式子方法.

>>> import re
>>> insensitive_hippo = re.compile(re.escape('hippo'), re.IGNORECASE)
>>> insensitive_hippo.sub('giraffe', 'I want a hIPpo for my birthday')
'I want a giraffe for my birthday'
Run Code Online (Sandbox Code Playgroud)

  • 如果你只是做一次替换,或者想要保存代码行,那么使用re.sub和(?i)标志的单个替换会更有效:re.sub('(?i)'+ re .escape('hippo'),'长颈鹿','我想要一个hIPpo为我的生日') (10认同)
  • 为'insensitive_hippo`投票赞成.此外,还提供相关文档的内联链接. (7认同)
  • @Elena,"hippo"不需要它,但如果将to-replace值传递给函数会很有用,所以它实际上比其他任何东西都更好. (6认同)
  • 为什么**re.escape**仅限一串字母?谢谢. (3认同)
  • 除了必须“重新逃脱”针头之外,这里还有另一个陷阱,这个答案无法避免,请参见http://stackoverflow.com/a/15831118/1709587:由于`re.sub`处理逃逸序列,如前所述在https://docs.python.org/library/re.html#re.sub中,您需要转义替换字符串中的所有反斜杠或使用lambda。 (2认同)

Unk*_*own 77

import re
pattern = re.compile("hello", re.IGNORECASE)
pattern.sub("bye", "hello HeLLo HELLO")
# 'bye bye bye'
Run Code Online (Sandbox Code Playgroud)

  • 或者单线:`re.sub('hello','bye','hello HeLLo HELLO',flags = re.IGNORECASE)` (5认同)

vie*_*bel 40

在一行中:

import re
re.sub("(?i)hello","bye", "hello HeLLo HELLO") #'bye bye bye'
re.sub("(?i)he\.llo","bye", "he.llo He.LLo HE.LLO") #'bye bye bye'
Run Code Online (Sandbox Code Playgroud)

或者,使用可选的"flags"参数:

import re
re.sub("hello", "bye", "hello HeLLo HELLO", flags=re.I) #'bye bye bye'
re.sub("he\.llo", "bye", "he.llo He.LLo HE.LLO", flags=re.I) #'bye bye bye'
Run Code Online (Sandbox Code Playgroud)


rsm*_*thy 12

继续bFloch的回答,这个函数将改变不是一个,而是所有出现的旧的new - 以不区分大小写的方式.

def ireplace(old, new, text):
    idx = 0
    while idx < len(text):
        index_l = text.lower().find(old.lower(), idx)
        if index_l == -1:
            return text
        text = text[:index_l] + new + text[index_l + len(old):]
        idx = index_l + len(new) 
    return text
Run Code Online (Sandbox Code Playgroud)

  • 做得太好了。比正则表达式好得多;它可以处理各种字符,而正则表达式对任何非字母数字的字符非常挑剔。首选答案恕我直言。 (3认同)

小智 7

该函数同时使用str.replace()re.findall()函数。它将以不区分大小写的方式替换所有出现的patternin 。stringrepl

def replace_all(pattern, repl, string) -> str:
   occurences = re.findall(pattern, string, re.IGNORECASE)
   for occurence in occurences:
       string = string.replace(occurence, repl)
       return string
Run Code Online (Sandbox Code Playgroud)


小智 6

这不需要正则表达式

def ireplace(old, new, text):
    """ 
    Replace case insensitive
    Raises ValueError if string not found
    """
    index_l = text.lower().index(old.lower())
    return text[:index_l] + new + text[index_l + len(old):] 
Run Code Online (Sandbox Code Playgroud)

  • 它的可读性不如正则表达式版本。无需在这里重新发明轮子。 (6认同)
  • 很好,但这并不会改变所有出现的旧的与新的,而只是第一次出现。 (3认同)

joh*_*ohv 6

就像布莱尔康拉德说的 string.replace 不支持这个。

使用 regex re.sub,但请记住先对替换字符串进行转义。请注意,2.6 for 中没有标志选项re.sub,因此您必须使用嵌入式修饰符'(?i)'(或 RE 对象,请参阅 Blair Conrad 的回答)。此外,另一个陷阱是 sub 将处理替换文本中的反斜杠转义,如果给定字符串。为了避免这种情况,可以改为传入 lambda。

这是一个函数:

import re
def ireplace(old, repl, text):
    return re.sub('(?i)'+re.escape(old), lambda m: repl, text)

>>> ireplace('hippo?', 'giraffe!?', 'You want a hiPPO?')
'You want a giraffe!?'
>>> ireplace(r'[binfolder]', r'C:\Temp\bin', r'[BinFolder]\test.exe')
'C:\\Temp\\bin\\test.exe'
Run Code Online (Sandbox Code Playgroud)


小智 6

关于语法细节和选项的有趣观察:

# Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
>>> import re
>>> old = "TREEROOT treeroot TREerOot"

>>> re.sub(r'(?i)treeroot', 'grassroot', old)
'grassroot grassroot grassroot'

>>> re.sub(r'treeroot', 'grassroot', old)
'TREEROOT grassroot TREerOot'

>>> re.sub(r'treeroot', 'grassroot', old, flags=re.I)
'grassroot grassroot grassroot'

>>> re.sub(r'treeroot', 'grassroot', old, re.I)
'TREEROOT grassroot TREerOot'
Run Code Online (Sandbox Code Playgroud)

(?i)在匹配表达式中使用前缀或添加flags=re.I为第四个参数将导致不区分大小写的匹配 - 但是仅用作re.I第四个参数不会导致不区分大小写的匹配。

用于比较:

>>> re.findall(r'treeroot', old, re.I)
['TREEROOT', 'treeroot', 'TREerOot']

>>> re.findall(r'treeroot', old)
['treeroot']
Run Code Online (Sandbox Code Playgroud)