Answers:
假设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)")
'ß'.lower() == 'SS'.lower()
是错误的。
以不区分大小写的方式比较字符串似乎很简单,但事实并非如此。我将使用Python 3,因为Python 2在这里尚未开发。
首先要注意的是,用Unicode删除大小写的转换并非易事。有一些文字text.lower() != text.upper().lower()
,例如"ß"
:
"ß".lower()
#>>> 'ß'
"ß".upper().lower()
#>>> 'ss'
但是,假设您想无休止地比较"BUSSE"
和"Buße"
。哎呀,您可能还想比较"BUSSE"
和"BUẞE"
相等-这是较新的资本形式。推荐的方式是使用casefold
:
海峡 折叠()
返回字符串的casefolded副本。折叠的字符串可用于无大小写的匹配。
大小写折叠类似于小写字母,但更具攻击性,因为它旨在消除字符串中的所有大小写区别。[...]
不要只是使用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)))
两面均为(D146,规范),两面均为(D147,兼容性)NFKD(toCasefold(NFKD(toCasefold(NFD(X)))))
。它指出内部NFD
仅用于处理某种希腊口音字符。我想这全都是边缘案例。
使用Python 2,调用.lower()
每个字符串或Unicode对象...
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
因此,如果您关心像希腊语中的三个sigma这样的边缘情况,请使用Python 3。
(供参考,上面的解释器打印输出中显示了Python 2.7.3和Python 3.3.0b1。)
Unicode标准的第3.13节定义了无大小写匹配的算法。
X.casefold() == Y.casefold()
在Python 3中实现了“默认无大小写匹配”(D144)。
Casefolding不能在所有实例中保留字符串的规范化,因此需要进行规范化('å'
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()
函数无法实现Case Folding Properties中所述的大写I和点分大写I的特殊情况处理。因此,对于包含这些字母的突厥语单词,比较可能会失败。例如,canonical_caseless('LİMANI') == canonical_caseless('limanı')
必须返回True
,但必须返回False
。当前,用Python处理此问题的唯一方法是编写一个casefold包装器或使用外部Unicode库,例如PyICU。
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)
....:
通常的方法是将字符串大写或小写以进行查找和比较。例如:
>>> "hello".upper() == "HELLO".upper()
True
>>>
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__)
您要做的就是将两个字符串转换为小写(所有字母都变为小写),然后进行比较(假设字符串是ASCII字符串)。
例如:
string1 = "Hello World"
string2 = "hello WorlD"
if string1.lower() == string2.lower():
print("The two strings are the same.")
else:
print("The two strings are not the same."
这是我在上个星期学习过爱/恨的另一个正则表达式,因此通常导入(在本例中为)反映我的感觉的东西!做一个正常的功能....要求输入,然后使用.... something = re.compile(r'foo * | spam *',是的.I)...... re.I(是的.I下方)与IGNORECASE相同,但是您编写时可能会犯很多错误!
然后,您可以使用正则表达式搜索消息,但老实说应该仅占几页,但要点是foo或垃圾邮件通过管道传递在一起,并且忽略大小写。然后,如果找到任何一个,则lost_n_found将显示其中之一。如果两者都不是,则lost_n_found等于无。如果不等于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")
Σίσυφος
和ΣΊΣΥΦΟΣ
,则您的方法将失败,因为应该以不区分大小写的方式区分它们。