2016-10-31 4 views
3

Kürzlich gelesen auf Fallfold und String-Vergleiche beim Ignorieren des Falls. Ich habe gelesen, dass der MSDN-Standard InvariantCulture verwenden und definitiv toLowercase vermeiden soll. Fallfold von dem, was ich gelesen habe, ist jedoch wie eine aggressivere toLowercase. Meine Frage ist, ob ich Catchfold in Python verwenden soll oder ob stattdessen ein pythonischer Standard verwendet werden soll. Wird der Türkei-Test auch erfolgreich bestanden?Sollte ich Python Casefold verwenden?

+2

1. Was 'casefold' tut, wird [in den Dokumenten] erklärt (https://docs.python.org/3/library/stdtypes.html#str.casefold). 2. Was bedeutet "besser" * in diesem Fall? 3. Was ist der Türkische Test (und hast du versucht ihn auszuführen, um es herauszufinden)? – jonrsharpe

+0

@jonrsharpe Sorry, meinte mehr pythisch und meinte auch Turkey Test. Ich möchte nur wissen, was gute Programmierer verwenden, wenn sie in Python halslose Vergleiche durchführen wollen. – FlyingLightning

+0

@jonrsharpe - der türkische Test wird hier genauer beschrieben http://stackoverflow.com/a/797043/135978 –

Antwort

4

1) In Python 3 sollte casefold() verwendet werden, um halslosen Zeichenfolgenabgleich zu implementieren.

Seit Python 3.0 werden Zeichenfolgen als Unicode gespeichert. The Unicode Standard Chapter 3.13 definiert die Standardhülsenlos passenden wie folgt:

Ein String X ist eine hülsenlose Übereinstimmung für eine Zeichenfolge Y, wenn und nur wenn:
toCasefold (X) = toCasefold (Y)

Python's casefold() implements the Unicode's toCasefold(). So sollte es verwendet werden, um hüllenlose Zeichenfolgenabgleich zu implementieren. Allerdings reicht die Falschgeldfaltung allein nicht aus, um einige Eckfälle abzudecken und den Türkei-Test zu bestehen (siehe Punkt 3).

2) Ab Cagedfax 3.6 kann casefold() den Turkey Test nicht bestehen.

Für zwei Zeichen, Großbuchstaben I und gepunktete Groß I, the Unicode Standard defines two different casefolding mappings.

Der Standard (für Nicht-Turksprachen):
I → I (U + 0049 → U + 0069)
i → I (U + 0130 → 0069 U + U + 0307)

Die alternative (für Turksprachen):
I → I (U + 0049 → U + 0131)
© → i (U + 0130 → U + 0069)

Pythons casefold() kann nur die Standardzuordnung anwenden und schlägt den Türkei-Test fehl. Zum Beispiel sind die türkischen Wörter "LİMANI" und "limanı" hülsenlose Entsprechungen, aber "LİMANI".casefold() == "limanı".casefold() gibt False zurück. Es gibt keine Option zum Aktivieren der alternativen Zuordnung.

3) Wie in Python 3.

The Unicode Standard Chapter 3.13 beschreibt mehrere hülsenlose Matching-Algorithmen hülsenlose String-Matching zu tun. Die kanonische casless übereinstimmende würde wahrscheinlich die meisten Anwendungsfälle passen. Dieser Algorithmus berücksichtigt bereits alle Eckfälle. Wir müssen nur eine Option hinzufügen, um zwischen nichttürkischer und turkischer Fallfalte zu wechseln.

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_() ist ein Wrapper für Python casefold(). Wenn der Parameter include_special_i auf True gesetzt ist, wird das Turkic-Mapping angewendet, und wenn es auf False festgelegt ist, wird das Standardmapping verwendet.

caseless_match() macht die kanonische casless passend für string1 und string2.Wenn die Zeichenfolgen turkische Wörter sind, muss include_special_i Parameter auf True festgelegt werden.

Beispiele:

caseless_match('LİMANI', 'limanı', include_special_i=True) Wahre

caseless_match('LİMANI', 'limanı') Falsch

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

caseless_match('INTENSIVE', 'intensive') Wahre

Verwandte Themen