簡體   English   中英

我應該使用 Python casefold 嗎?

[英]Should I use Python casefold?

最近在閱讀忽略大小寫時的 casefold 和字符串比較。 我讀過 MSDN 標准是使用 InvariantCulture 並且絕對避免使用 toLowercase。 然而,從我所讀到的 casefold 就像一個更激進的 toLowercase。 我的問題是我應該在 Python 中使用 casefold 還是有更多的 Pythonic 標准來代替? 另外,casefold 是否通過了土耳其測試?

1) 在 Python 3 中,應該使用casefold()來實現無大小寫的字符串匹配。

從 Python 3.0 開始,字符串存儲為 Unicode。 Unicode 標准第 3.13 章定義了默認的 caseless 匹配如下:

字符串 X 是字符串 Y 的無大小寫匹配,當且僅當:
toCasefold(X) = toCasefold(Y)

Python 的casefold()實現了 Unicode 的toCasefold() 所以,應該用它來實現無大小寫的字符串匹配。 盡管如此,單靠案例折疊還不足以覆蓋一些極端案例並通過土耳其測試(參見第 3 點)。

2) 從 Python 3.6 開始,casefold() 無法通過土耳其測試。

對於大寫 I 和點分大寫 I 這兩個字符, Unicode 標准定義了兩種不同的 casefolding 映射。

默認值(對於非突厥語言):
我 → 我 (U+0049 → U+0069)
© → i̇ (U+0130 → U+0069 U+0307)

替代方案(對於突厥語):
I → ı (U+0049 → U+0131)
© → i (U+0130 → U+0069)

Python 的casefold()只能應用默認映射並且無法通過土耳其測試。 例如,土耳其語單詞 "LİMANI" 和 "limanı" 是無殼等價物,但"LİMANI".casefold() == "limanı".casefold()返回False 沒有啟用替代映射的選項。

3) 如何在 Python 3 中進行無大小寫的字符串匹配。

Unicode 標准第 3.13 章描述了幾種無殼匹配算法。 規范的 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進行規范的caseless_match()殼匹配。 如果字符串是突厥語詞,則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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM