Koz*_*huk 525 python comparison case-insensitive
如何在Python中进行不区分大小写的字符串比较?
我想以一种非常简单和Pythonic的方式将常规字符串的比较封装到存储库字符串中.我还希望能够使用常规python字符串在字符串中查找值.
Har*_*mbe 554
假设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)")
Run Code Online (Sandbox Code Playgroud)
Vee*_*rac 460
以不区分大小写的方式比较字符串似乎是微不足道的,但事实并非如此.我将使用Python 3,因为Python 2在这里不发达.
首先要注意的是,在unicode中删除大小写的转换并非易事.有文字text.lower() != text.upper().lower(),例如"ß":
"ß".lower()
#>>> 'ß'
"ß".upper().lower()
#>>> 'ss'
Run Code Online (Sandbox Code Playgroud)
但是,让我们说你想无谓地比较"BUSSE"和"Buße".哎呀,你可能也想比较"BUSSE"和"BU?E"平等 - 这是更新的资本形式.推荐的方法是使用casefold:
"ê" == "e?"
#>>> False
Run Code Online (Sandbox Code Playgroud)
不要只是使用lower.如果casefold不可用,做.upper().lower()帮助(但只是有点).
那你应该考虑口音.如果您的字体渲染器很好,您可能会想"ê" == "e?"- 但它不是:
import unicodedata
[unicodedata.name(char) for char in "ê"]
#>>> ['LATIN SMALL LETTER E WITH CIRCUMFLEX']
[unicodedata.name(char) for char in "e?"]
#>>> ['LATIN SMALL LETTER E', 'COMBINING CIRCUMFLEX ACCENT']
Run Code Online (Sandbox Code Playgroud)
这是因为它们实际上是
unicodedata.normalize("NFKD", "ê") == unicodedata.normalize("NFKD", "e?")
#>>> True
Run Code Online (Sandbox Code Playgroud)
解决这个问题最简单的方法是unicodedata.normalize.您可能想要使用NFKD规范化,但请随时查看文档.然后一个人
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
Run Code Online (Sandbox Code Playgroud)
最后,这里用函数表示:
"ß".lower()
#>>> 'ß'
"ß".upper().lower()
#>>> 'ss'
Run Code Online (Sandbox Code Playgroud)
Nat*_*ike 58
使用Python 2,调用.lower()每个字符串或Unicode对象......
string1.lower() == string2.lower()
Run Code Online (Sandbox Code Playgroud)
......大部分时间都会工作,但在@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
Run Code Online (Sandbox Code Playgroud)
Σ字符有两个小写形式,ς和σ,并且.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
Run Code Online (Sandbox Code Playgroud)
因此,如果您关注像希腊语中的三个sigma这样的边缘情况,请使用Python 3.
(作为参考,Python 2.7.3和Python 3.3.0b1显示在上面的解释器打印输出中.)
jfs*_*jfs 33
Unicode标准的第3.13节定义了无壳匹配的算法.
X.casefold() == Y.casefold() 在Python 3中实现了"默认的无壳匹配"(D144).
Casefolding不保留所有实例中字符串的规范化,因此需要进行规范化('å'vs. 'a?').D145引入了"规范无壳匹配":
import unicodedata
def NFD(text):
return unicodedata.normalize('NFD', text)
def canonical_caseless(text):
return NFD(NFD(text).casefold())
Run Code Online (Sandbox Code Playgroud)
NFD() 对于涉及U + 0345字符的非常罕见的边缘情况,会被调用两次.
例:
>>> 'å'.casefold() == 'a?'.casefold()
False
>>> canonical_caseless('å') == canonical_caseless('a?')
True
Run Code Online (Sandbox Code Playgroud)
对于诸如'?'(U + 3392)和"标识符无标记匹配"的情况,还存在兼容性无情况匹配(D146),以简化和优化标识符的无边界匹配.
小智 7
import re
if re.search('mandy', 'Mandy Pande', re.IGNORECASE):
# is True
Run Code Online (Sandbox Code Playgroud)
它适用于重音
In [42]: if re.search("ê","ê", re.IGNORECASE):
....: print(1)
....:
1
Run Code Online (Sandbox Code Playgroud)
但是,它不适用于不区分大小写的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)
....:
Run Code Online (Sandbox Code Playgroud)
您可以使用 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.')
Run Code Online (Sandbox Code Playgroud)
输出:
The strings are equal.
Run Code Online (Sandbox Code Playgroud)