2015-05-05 16 views
12

Nella scrittura latina, le lettere hanno una maiuscola e una minuscola. In Python, se vuoi confrontare due stringhe senza riguardo al loro caso, puoi convertirle nello stesso caso usando 'string'.upper() o 'string'.lower()Esiste un modo per confrontare i caratteri arabi senza riguardo alla loro forma iniziale/mediale/finale?

Nella scrittura araba, le lettere possono avere una forma iniziale, mediale o finale. Esiste un modo simile per confrontare stringhe di caratteri arabi senza preoccuparsi di quale forma sono le lettere?

+0

Non direttamente. Stai effettivamente cercando di convertire tutti i personaggi in una forma mediale, o stai facendo quello (a) per fare l'equivalente arabo del confronto senza distinzione tra maiuscole e minuscole (o ordinamento, ecc.), O (b) per generare l'arabo equivalente del caso di frase inglese o del titolo? Perché ci sono modi per farlo direttamente. – abarnert

+0

@abarnert, sto cercando di fare il primo: l'equivalente arabo del confronto insensibile alle maiuscole inglese. – drs

+1

Se davvero si ha bisogno di convertire i caratteri in un modulo mediale, è necessario applicare manualmente le informazioni dal database Unicode. Python ha una grossa fetta del database nel suo modulo 'unicodedata'; se hai bisogno di più, puoi scaricare e analizzare i file da 'unicode.org' o cercare moduli di terze parti su PyPI. (Dovrei controllare se ha abbastanza per questo scopo ...) – abarnert

risposta

6

ci sono due parti in questo, che dovrebbe funzionare per tutte le lingue: *

  • vostre corde devono essere in NFKD normalizzazione per garantire che due stringhe uguali hanno unità di codice uguali.
  • Per ignorare il caso nel confronto di due stringhe NFKD, utilizzare l'algoritmo di piegatura del caso Unicode.

Tra i due, questo maniglie lettere maiuscole e minuscole inglese, arabo iniziale/mediale/finale (più isolato), Tedesco ß contro ss, é come punto unico codice vs. e\N{COMBINING ACUTE ACCENT}, cinese, giapponese ruotato caratteri kana a mezza larghezza e probabilmente tutti i tipi di altre cose a cui non hai pensato.

In Python, che assomiglia a questo:

>>> s1 = 'ﻧ' 
>>> s2 = 'ﻨ' 
>>> unicodedata.normalize('NFKD', s1).casefold() == unicodedata.normalize('NFKD', s2) 
True 

Nota che casefold non è stato aggiunto fino Python 3.3. Se stai usando una versione precedente di Python, ci sono implementazioni su PyPI; utilizzarli dovrebbe essere simile all'utilizzo del built-in 3.3+.


Se siete interessati a esattamente come questo funziona per l'arabo, piuttosto che solo il fatto che funziona per l'arabo insieme ad ogni altra lingua, hanno letto gli algoritmi e le tabelle a unicode.org. IIRC, il documento W3C che consiglia di fare questo spiega perché funziona usando l'arabo come esempio. Credo che sia perché Unicode tratta le forme di presentazione iniziali, mediali, finali e isolate come equivalenti di compatibilità dello stesso carattere, quindi la normalizzazione a scomposti ti dà la forma isolata più un modificatore che può essere saltato o trasformato, anche se il casefolding direttamente un personaggio combinato restituisce semplicemente il personaggio stesso.


* Ci sono alcuni casi in cui due lingue o culture diverse utilizzare lo stesso copione, ma hanno regole diverse-pieghevole di caso; in tal caso, è necessario il casefolding specifico per locale, che Python non include. Ma questo non dovrebbe essere rilevante qui.