最近在忽略大小写时阅读了casefold和字符串比较。我读过,MSDN标准是使用InvariantCulture,并且绝对避免使用小写。但是,从我读到的案例来看,casefold对于小写字母来说更具攻击性。我的问题是我应该在Python中使用casefold还是要使用更多的pythonic标准呢?另外,保护套是否通过了土耳其测试?

最佳答案

1) 在 Python 3 中,应该使用 casefold() 来实现无大小写的字符串匹配。
从 Python 3.0 开始,字符串存储为 Unicode。 The Unicode Standard Chapter 3.13 定义了默认的无 shell 匹配如下:

Python's casefold() implements the Unicode's toCasefold() . 所以,应该是用来实现caseless字符串匹配的。尽管如此,单靠案例折叠还不足以覆盖一些极端案例并通过土耳其测试(参见第 3 点)。
2) 从 Python 3.6 开始,casefold() 无法通过土耳其测试。
对于两个字符,大写 I 和点状大写 I,the Unicode Standard defines two different casefolding mappings.
默认值(对于非突厥语言):
我 → 我 (U+0049 → U+0069)
© → i̇ (U+0130 → U+0069 U+0307)
替代方案(对于突厥语):
I → ı (U+0049 → U+0131)
© → i (U+0130 → U+0069)
Pythons casefold() 只能应用默认映射,并没有通过土耳其测试。例如,土耳其语单词“LİMANI”和“limanı”是无大小写的等价物,但 "LİMANI".casefold() == "limanı".casefold() 返回 False 。没有启用替代映射的选项。
3) 如何在 Python 3 中进行无大小写的字符串匹配。
The Unicode Standard Chapter 3.13 描述了几种无 shell 匹配算法。规范的 casless 匹配可能适合大多数用例。该算法已经考虑了所有极端情况。我们只需要添加一个选项来在非突厥语和突厥语casefolding 之间切换。

import unicodedata

def normalize_NFD(string):
    return unicodedata.normalize('NFD', string)

def casefold_(string, include_special_i=False):
    if include_special_i:
        string = unicodedata.normalize('NFC', string)
        string = string.replace('\u0049', '\u0131')
        string = string.replace('\u0130', '\u0069')
    return string.casefold()

def casefold_NFD(string, include_special_i=False):
    return normalize_NFD(casefold_(normalize_NFD(string), include_special_i))

def caseless_match(string1, string2, include_special_i=False):
    return  casefold_NFD(string1, include_special_i) == casefold_NFD(string2, include_special_i)
casefold_() 是 Python 的 casefold() 的包装器。如果其参数 include_special_i 设置为 True ,则应用突厥语映射,如果设置为 False 则使用默认映射。caseless_match()string1string2 进行规范的 casless 匹配。如果字符串是突厥语词,则必须将 include_special_i 参数设置为 True
示例:
>>> caseless_match('LİMANI', 'limanı', include_special_i=True)
True
>>> caseless_match('LİMANI', 'limanı')
False
>>> caseless_match('INTENSIVE', 'intensive', include_special_i=True)
False
>>> caseless_match('INTENSIVE', 'intensive')
True

关于python - 我应该使用 Python casefold 吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40348174/

10-14 19:29
查看更多