如何在Python中以不区分大小写的方式比较字符串?
我想使用简单的python代码将常规字符串的比较封装到存储库字符串中。我也想有能力在字典中查找值哈希字符串使用常规的python字符串。
如何在Python中以不区分大小写的方式比较字符串?
我想使用简单的python代码将常规字符串的比较封装到存储库字符串中。我也想有能力在字典中查找值哈希字符串使用常规的python字符串。
当前回答
假设ASCII字符串:
string1 = 'Hello'
string2 = 'hello'
if string1.lower() == string2.lower():
print("The strings are the same (case insensitive)")
else:
print("The strings are NOT the same (case insensitive)")
从Python 3.3开始,casefold()是一个更好的选择:
string1 = 'Hello'
string2 = 'hello'
if string1.casefold() == string2.casefold():
print("The strings are the same (case insensitive)")
else:
print("The strings are NOT the same (case insensitive)")
如果您想要一个处理更复杂unicode比较的更全面的解决方案,请参阅其他答案。
其他回答
from re import search, IGNORECASE
def is_string_match(word1, word2):
# Case insensitively function that checks if two words are the same
# word1: string
# word2: string | list
# if the word1 is in a list of words
if isinstance(word2, list):
for word in word2:
if search(rf'\b{word1}\b', word, IGNORECASE):
return True
return False
# if the word1 is same as word2
if search(rf'\b{word1}\b', word2, IGNORECASE):
return True
return False
is_match_word = is_string_match("Hello", "hELLO")
True
is_match_word = is_string_match("Hello", ["Bye", "hELLO", "@vagavela"])
True
is_match_word = is_string_match("Hello", "Bye")
False
以不区分大小写的方式比较字符串似乎无关紧要,但事实并非如此。我将使用Python 3,因为Python 2在这里还不发达。
首先要注意的是,Unicode中的大小写删除转换并不简单。存在text.lower() != text.upper().lower()的文本,例如"ß":
>>> "ß".lower()
'ß'
>>> "ß".upper().lower()
'ss'
但是让我们假设你想无案例地比较“BUSSE”和“Buße”。见鬼,您可能还想比较“BUSSE”和“BUẞE”相等——这是较新的大写形式。推荐使用casefold:
str.casefold () 返回字符串的大小写折叠副本。折叠的字符串可用于 caseless匹配。 大小写折叠类似于小写,但更激进,因为它是 用于删除字符串中的所有大小写区别。[…]
不要只使用lower。如果casefold不可用,执行.upper().lower()会有所帮助(但只是略有帮助)。
然后你应该考虑口音。如果你的字体渲染器很好,你可能认为“ê”==“ê”-但它不是:
>>> "ê" == "ê"
False
这是因为后者的重音是一个组合字符。
>>> import unicodedata
>>> [unicodedata.name(char) for char in "ê"]
['LATIN SMALL LETTER E WITH CIRCUMFLEX']
>>> [unicodedata.name(char) for char in "ê"]
['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT']
最简单的处理方法是unicodedata.normalize。您可能希望使用NFKD规范化,但请随意查看文档。然后有人会这么做
>>> unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "ê")
True
最后,这里用函数表示:
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
Unicode标准的第3.13节定义了无大小写的算法 匹配。
X.casefold() == Python 3中的Y.casefold()实现了“默认的无大小写匹配”(D144)。
案例折叠不会在所有实例中保存字符串的规范化,因此需要进行规范化('å' vs。“一个”)。D145引入了“规范无大小写匹配”:
import unicodedata
def NFD(text):
return unicodedata.normalize('NFD', text)
def canonical_caseless(text):
return NFD(NFD(text).casefold())
对于涉及U+0345字符的非常罕见的边缘情况,NFD()被调用两次。
例子:
>>> 'å'.casefold() == 'å'.casefold()
False
>>> canonical_caseless('å') == canonical_caseless('å')
True
此外,还有兼容无案例匹配(D146),如“mhz”(U+3392)和“标识符无案例匹配”,以简化和优化标识符的无案例匹配。
使用Python 2,在每个字符串或Unicode对象上调用.lower()…
string1.lower() == string2.lower()
...大部分时间都有效,但在@tchrist所描述的情况下确实不起作用。
假设我们有一个名为unicode.txt的文件,其中包含两个字符串Σίσυφος和ΣΊΣΥΦΟΣ。使用Python 2:
>>> utf8_bytes = open("unicode.txt", 'r').read()
>>> print repr(utf8_bytes)
'\xce\xa3\xce\xaf\xcf\x83\xcf\x85\xcf\x86\xce\xbf\xcf\x82\n\xce\xa3\xce\x8a\xce\xa3\xce\xa5\xce\xa6\xce\x9f\xce\xa3\n'
>>> u = utf8_bytes.decode('utf8')
>>> print u
Σίσυφος
ΣΊΣΥΦΟΣ
>>> first, second = u.splitlines()
>>> print first.lower()
σίσυφος
>>> print second.lower()
σίσυφοσ
>>> first.lower() == second.lower()
False
>>> first.upper() == second.upper()
True
Σ字符有两种小写形式ς和Σ, .lower()不能区分大小写进行比较。
然而,从Python 3开始,这三种表单都将解析为ς,并且在两个字符串上调用lower()将正确工作:
>>> s = open('unicode.txt', encoding='utf8').read()
>>> print(s)
Σίσυφος
ΣΊΣΥΦΟΣ
>>> first, second = s.splitlines()
>>> print(first.lower())
σίσυφος
>>> print(second.lower())
σίσυφος
>>> first.lower() == second.lower()
True
>>> first.upper() == second.upper()
True
所以如果你关心边界情况,比如希腊语中的3 sigma,请使用python3。
(作为参考,Python 2.7.3和Python 3.3.0b1显示在上面的解释器打印输出中。)
假设ASCII字符串:
string1 = 'Hello'
string2 = 'hello'
if string1.lower() == string2.lower():
print("The strings are the same (case insensitive)")
else:
print("The strings are NOT the same (case insensitive)")
从Python 3.3开始,casefold()是一个更好的选择:
string1 = 'Hello'
string2 = 'hello'
if string1.casefold() == string2.casefold():
print("The strings are the same (case insensitive)")
else:
print("The strings are NOT the same (case insensitive)")
如果您想要一个处理更复杂unicode比较的更全面的解决方案,请参阅其他答案。