不区分大小写的替换

发布于 2024-07-23 10:15:30 字数 41 浏览 7 评论 0原文

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

What's the easiest way to do a case-insensitive string replacement in Python?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

你穿错了嫁妆 2024-07-30 10:15:30

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'

The string type doesn't support this. You're probably best off using the regular expression sub method with the re.IGNORECASE option.

>>> 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'
听风念你 2024-07-30 10:15:30
import re
pattern = re.compile("hello", re.IGNORECASE)
pattern.sub("bye", "hello HeLLo HELLO")
# 'bye bye bye'
import re
pattern = re.compile("hello", re.IGNORECASE)
pattern.sub("bye", "hello HeLLo HELLO")
# 'bye bye bye'
昔梦 2024-07-30 10:15:30

在一行中:

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'

或者,使用可选的“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'

In a single line:

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'

Or, use the optional "flags" argument:

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'
归途 2024-07-30 10:15:30

继续 bFloch 的答案,这个函数不会改变一个,而是所有出现的旧的都会变成新的——以一种不区分大小写的方式。

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

Continuing on bFloch's answer, this function will change not one, but all occurrences of old with new - in a case insensitive fashion.

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
如梦 2024-07-30 10:15:30

就像 Blair Conrad 所说 string.replace 不支持这一点。

使用正则表达式 re.sub,但请记住首先转义替换字符串。 请注意,2.6 中没有 re.sub 的标志选项,因此您必须使用嵌入修饰符 '(?i)' (或 RE 对象,参见布莱尔·康拉德的回答)。 另外,另一个陷阱是,如果给出了字符串,则 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'

Like Blair Conrad says string.replace doesn't support this.

Use the regex re.sub, but remember to escape the replacement string first. Note that there's no flags-option in 2.6 for re.sub, so you'll have to use the embedded modifier '(?i)' (or a RE-object, see Blair Conrad's answer). Also, another pitfall is that sub will process backslash escapes in the replacement text, if a string is given. To avoid this one can instead pass in a lambda.

Here's a function:

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'
み零 2024-07-30 10:15:30

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

# 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'

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

用于比较:

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

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

An interesting observation about syntax details and options:

# 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'

Using the (?i) prefix in the match expression or adding flags=re.I as a fourth argument will result in a case-insensitive match - however using just re.I as the fourth argument does not result in case-insensitive match.

For comparison:

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

>>> re.findall(r'treeroot', old)
['treeroot']
贱贱哒 2024-07-30 10:15:30

此函数同时使用 str.replace()re.findall() 函数。
它将以不区分大小写的方式将 string 中所有出现的 pattern 替换为 repl

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

This function uses both the str.replace() and re.findall() functions.
It will replace all occurences of pattern in string with repl in a case-insensitive way.

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
雄赳赳气昂昂 2024-07-30 10:15:30

这不需要正则表达式

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):] 

This doesn't require RegularExp

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):] 
青萝楚歌 2024-07-30 10:15:30

我将 \t 转换为 转义序列 (向下滚动一点),所以我注意到 re.sub 将反斜杠转义字符转换为转义序列。

为了防止这种情况,我写了以下内容:

替换不区分大小写。

import re
    def ireplace(findtxt, replacetxt, data):
        return replacetxt.join(  re.compile(findtxt, flags=re.I).split(data)  )

另外,如果您希望它替换为转义字符,就像此处的其他答案一样,将特殊含义的 bashslash 字符转换为转义序列,只需解码您的查找和/或替换字符串即可。 在 Python 3 中,可能需要执行类似 .decode("unicode_escape") # python3

findtxt = findtxt.decode('string_escape') # python2
replacetxt = replacetxt.decode('string_escape') # python2
data = ireplace(findtxt, replacetxt, data)

在 Python 2.7.8 中测试的操作

I was having \t being converted to the escape sequences (scroll a bit down), so I noted that re.sub converts backslashed escaped characters to escape sequences.

To prevent that I wrote the following:

Replace case insensitive.

import re
    def ireplace(findtxt, replacetxt, data):
        return replacetxt.join(  re.compile(findtxt, flags=re.I).split(data)  )

Also, if you want it to replace with the escape characters, like the other answers here that are getting the special meaning bashslash characters converted to escape sequences, just decode your find and, or replace string. In Python 3, might have to do something like .decode("unicode_escape") # python3

findtxt = findtxt.decode('string_escape') # python2
replacetxt = replacetxt.decode('string_escape') # python2
data = ireplace(findtxt, replacetxt, data)

Tested in Python 2.7.8

征棹 2024-07-30 10:15:30
i='I want a hIPpo for my birthday'
key='hippo'
swp='giraffe'

o=(i.lower().split(key))
c=0
p=0
for w in o:
    o[c]=i[p:p+len(w)]
    p=p+len(key+w)
    c+=1
print(swp.join(o))
i='I want a hIPpo for my birthday'
key='hippo'
swp='giraffe'

o=(i.lower().split(key))
c=0
p=0
for w in o:
    o[c]=i[p:p+len(w)]
    p=p+len(key+w)
    c+=1
print(swp.join(o))
星星的軌跡 2024-07-30 10:15:30

1 行简单解决方案,无需导入:-)

words = 'GREETINGS from EGYPT. GreeTings from Cairo'
replace_what, replace_with,  = 'Greetings', 'Hello'

result = ' '.join([replace_with if word.lower() == replace_what.lower() else word for word in words.split(' ')])
print (result)

结果是:

Hello from EGYPT. Hello from Cairo

1 line simple solution without imports :-)

words = 'GREETINGS from EGYPT. GreeTings from Cairo'
replace_what, replace_with,  = 'Greetings', 'Hello'

result = ' '.join([replace_with if word.lower() == replace_what.lower() else word for word in words.split(' ')])
print (result)

The result is:

Hello from EGYPT. Hello from Cairo
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文