我应该使用Python casefold吗?

Fly*_*ing 4 python python-3.x case-folding

最近在忽略案例时阅读了案例折叠和字符串比较.我已经读过,MSDN标准是使用InvariantCulture,绝对避免使用toLowercase.然而,我所读到的案例翻译就像是一个更具攻击性的低级版.我的问题是我应该在Python中使用casefold还是使用更多的pythonic标准?案件折叠是否通过土耳其测试?

Ser*_*kov 9

1)在Python 3中,casefold()应该用于实现无壳字符串匹配.

从Python 3.0开始,字符串存储为Unicode.Unicode标准第3.13章定义了默认的无壳匹配,如下所示:

字符串X是字符串Y的无壳匹配,当且仅当:
toCasefold(X)= toCasefold(Y)

Python casefold()实现了Unicode toCasefold().所以它应该用于实现无壳字符串匹配.虽然,单独的案例折叠不足以涵盖一些角落案件并通过土耳其测试(见第3点).

2)从Python 3.6开始,casefold()无法通过土耳其测试.

对于两个字符,大写字母I和点缀大写字母I,Unicode标准定义了两个不同的casefolding映射.

默认(对于非突厥语言):
I→i(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中进行无壳字符串匹配.

Unicode标准第3.13章描述了几种无壳匹配算法.该规范casless匹配可能会适合大多数使用情况.该算法已经考虑了所有极端情况.我们只需要添加一个选项来切换非突厥和突厥的案例折叠.

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)
Run Code Online (Sandbox Code Playgroud)

casefold_()是Python的包装器casefold().如果其参数include_special_i设置为True,则它应用Turkic映射,如果设置为False默认映射则使用.

caseless_match()做为规范casless匹配string1string2.如果字符串是突厥语单词,则include_special_i必须将参数设置为True.

例子:

caseless_match('L?MANI', 'liman?', include_special_i=True) 真正

caseless_match('L?MANI', 'liman?')

caseless_match('INTENSIVE', 'intensive', include_special_i=True)

caseless_match('INTENSIVE', 'intensive') 真正