提问人:Kozyarchuk 提问时间:11/26/2008 最后编辑:Karl KnechtelKozyarchuk 更新时间:11/12/2022 访问量:1148689
如何进行不区分大小写的字符串比较?
How do I do a case-insensitive string comparison?
问:
如何在 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 比较,请参阅其他答案。
评论
Σίσυφος
ΣΊΣΥΦΟΣ
'ß'.lower() == 'SS'.lower()
通常的方法是将字符串大写或小写,以便进行查找和比较。例如:
>>> "hello".upper() == "HELLO".upper()
True
>>>
先转换为小写怎么样?您可以使用 .string.lower()
评论
Σίσυφος
ΣΊΣΥΦΟΣ
def insenStringCompare(s1, s2):
""" Method that takes two strings and returns True or False, based
on if they are equal, regardless of case."""
try:
return s1.lower() == s2.lower()
except AttributeError:
print "Please only pass strings into this method."
print "You passed a %s and %s" % (s1.__class__, s2.__class__)
评论
使用 Python 2,调用每个字符串或 Unicode 对象....lower()
string1.lower() == string2.lower()
...大部分时间都有效,但在@tchrist描述的情况下确实不起作用。
假设我们有一个名为的文件,其中包含两个字符串和 。使用 Python 2:unicode.txt
Σίσυφος
ΣΊΣΥΦΟΣ
>>> 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
因此,如果您关心像希腊语中的三西格玛这样的边缘情况,请使用 Python 3。
(作为参考,Python 2.7.3 和 Python 3.3.0b1 显示在上面的解释器打印输出中。
评论
以不区分大小写的方式比较字符串似乎微不足道,但事实并非如此。我将使用 Python 3,因为 Python 2 在这里还不发达。
首先要注意的是,Unicode 中去除大小写的转换并非易事。有 的 文本 ,例如 :text.lower() != text.upper().lower()
"ß"
>>> "ß".lower()
'ß'
>>> "ß".upper().lower()
'ss'
但是,假设您想无大小写地比较 和 .哎呀,你可能还想比较和相等——这是较新的资本形式。推荐的方法是使用 casefold
:"BUSSE"
"Buße"
"BUSSE"
"BUẞE"
str.casefold()
返回字符串的折叠副本。折叠的绳子可用于 无大小写匹配。
外壳折叠类似于低壳,但更具侵略性,因为它是 旨在删除字符串中的所有大小写区别。[...]
不要只使用 .如果没有,做会有所帮助(但只是一些)。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)
评论
x.casefold() == y.casefold()
x == y
NFD(toCasefold(NFD(str)))
NFKD(toCasefold(NFKD(toCasefold(NFD(X)))))
NFD
import re
if re.search('mandy', 'Mandy Pande', re.IGNORECASE):
# is True
它适用于口音
In [42]: if re.search("ê","ê", re.IGNORECASE):
....: print(1)
....:
1
但是,它不适用于不区分大小写的 unicode 字符。谢谢你@Rhymoid指出,我的理解是它需要确切的符号,才能使案件成立。输出如下:
In [36]: "ß".lower()
Out[36]: 'ß'
In [37]: "ß".upper()
Out[37]: 'SS'
In [38]: "ß".upper().lower()
Out[38]: 'ss'
In [39]: if re.search("ß","ßß", re.IGNORECASE):
....: print(1)
....:
1
In [40]: if re.search("SS","ßß", re.IGNORECASE):
....: print(1)
....:
In [41]: if re.search("ß","SS", re.IGNORECASE):
....: print(1)
....:
评论
ß
SS
Unicode 标准的第 3.13 节定义了无大小写的算法 匹配。
X.casefold() == Y.casefold()
在 Python 3 中实现了“默认无大小写匹配”(D144)。
大小写折叠不会在所有情况下都保留字符串的规范化,因此需要进行规范化 ( vs. )。D145 引入了“规范无大小写匹配”:'å'
'å'
import unicodedata
def NFD(text):
return unicodedata.normalize('NFD', text)
def canonical_caseless(text):
return NFD(NFD(text).casefold())
NFD()
对于涉及 U+0345 字符的非常罕见的边缘情况,被调用两次。
例:
>>> 'å'.casefold() == 'å'.casefold()
False
>>> canonical_caseless('å') == canonical_caseless('å')
True
对于(U+3392)和“标识符无大小写匹配”等情况,还有兼容性无大小写匹配(D146),以简化和优化标识符的无大小写匹配。'㎒'
评论
casefold()
canonical_caseless('LİMANI') == canonical_caseless('limanı')
True
False
这是我上周学会爱/恨的另一个正则表达式,所以通常导入(在这种情况下是,是的)反映我的感受的东西! 做一个正常的功能......请求输入,然后使用 ....something = re.compile(r'foo*|spam*',是的。I)......再。我(是的。我在下面)与 IGNORECASE 相同,但你不能在写它时犯那么多错误!
然后你使用正则表达式搜索你的消息,但老实说,这应该是它自己的几个页面,但关键是 foo 或垃圾邮件被管道连接在一起,大小写被忽略。 然后,如果找到其中任何一个,那么lost_n_found将显示其中一个。如果两者都不是,则 lost_n_found 等于 None。如果它不等于 none,则使用“return lost_n_found.lower()”以小写形式返回user_input
这使您可以更轻松地匹配区分大小写的任何内容。最后,(NCS)代表“没有人认真关心......!”或不区分大小写。无论
如果有人有任何问题,请告诉我。.
import re as yes
def bar_or_spam():
message = raw_input("\nEnter FoO for BaR or SpaM for EgGs (NCS): ")
message_in_coconut = yes.compile(r'foo*|spam*', yes.I)
lost_n_found = message_in_coconut.search(message).group()
if lost_n_found != None:
return lost_n_found.lower()
else:
print ("Make tea not love")
return
whatz_for_breakfast = bar_or_spam()
if whatz_for_breakfast == foo:
print ("BaR")
elif whatz_for_breakfast == spam:
print ("EgGs")
您可以在 str.contains() 中提及 case=False
data['Column_name'].str.contains('abcd', case=False)
你可以使用 casefold() 方法。casefold() 方法在比较时忽略事例。
firstString = "Hi EVERYONE"
secondString = "Hi everyone"
if firstString.casefold() == secondString.casefold():
print('The strings are equal.')
else:
print('The strings are not equal.')
输出:
The strings are equal.
def search_specificword(key, stng):
key = key.lower()
stng = stng.lower()
flag_present = False
if stng.startswith(key+" "):
flag_present = True
symb = [',','.']
for i in symb:
if stng.find(" "+key+i) != -1:
flag_present = True
if key == stng:
flag_present = True
if stng.endswith(" "+key):
flag_present = True
if stng.find(" "+key+" ") != -1:
flag_present = True
print(flag_present)
return flag_present
输出: search_specificword(“经济适用房”,“欧洲经济适用房的核心”) 假
search_specificword(“经济适用房”,“欧洲经济适用房的核心”) 真
我找到了一个干净的解决方案,我正在处理一些恒定的文件扩展名。
from pathlib import Path
class CaseInsitiveString(str):
def __eq__(self, __o: str) -> bool:
return self.casefold() == __o.casefold()
GZ = CaseInsitiveString(".gz")
ZIP = CaseInsitiveString(".zip")
TAR = CaseInsitiveString(".tar")
path = Path("/tmp/ALL_CAPS.TAR.GZ")
GZ in path.suffixes, ZIP in path.suffixes, TAR in path.suffixes, TAR == ".tAr"
# (True, False, True, True)
评论
__hash__
class StrEnum(str, Enum):...
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
考虑使用 jaraco.text 中的 FoldedCase:
>>> from jaraco.text import FoldedCase
>>> FoldedCase('Hello World') in ['hello world']
True
如果你想要一个字典,不管大小写都以文本为键,请使用 jaraco.collections 中的 FoldedCaseKeyedDict:
>>> from jaraco.collections import FoldedCaseKeyedDict
>>> d = FoldedCaseKeyedDict()
>>> d['heLlo'] = 'world'
>>> list(d.keys()) == ['heLlo']
True
>>> d['hello'] == 'world'
True
>>> 'hello' in d
True
>>> 'HELLO' in d
True
评论