[python] Giocare con i personaggi di Devanagari



Answers

Quindi, vuoi ottenere qualcosa di simile

a[0] = बि a[1] = क्र a[3] = म

Il mio consiglio è di abbandonare l'idea che l'indicizzazione delle stringhe corrisponda ai caratteri che vedi sullo schermo. Devanagari, così come molti altri script, non funzionano bene con i programmatori che sono cresciuti con caratteri latini. Suggerisco di leggere lo standard Unicode capitolo 9 ( disponibile qui ).

Sembra che quello che stai cercando di fare è rompere una stringa in grapheme cluster. L'indicizzazione delle stringhe di per sé non ti consente di farlo. Hangul è un altro script che gioca male con l'indicizzazione delle stringhe, sebbene con la combinazione di caratteri, anche qualcosa di familiare come lo spagnolo causerà problemi.

Avrai bisogno di una libreria esterna come ICU per raggiungere questo obiettivo (a meno che tu non abbia molto tempo libero). ICU ha collegamenti Python.

>>> a = u"बिक्रम मेरो नाम हो"
>>> import icu
    # Note: This next line took a lot of guesswork.  The C, C++, and Java
    # interfaces have better documentation.
>>> b = icu.BreakIterator.createCharacterInstance(icu.Locale())
>>> b.setText(a)
>>> i = 0
>>> for j in b:
...     s = a[i:j]
...     print '|', s, len(s)
...     i = j
... 
| बि 2
| क् 2
| र 1
| म 1
|   1
| मे 2
| रो 2
|   1
| ना 2
| म 1
|   1
| हो 2

Nota come alcuni di questi "caratteri" (grapheme cluster) hanno lunghezza 2, e alcuni hanno lunghezza 1. Ecco perché l'indicizzazione delle stringhe è problematica: se voglio ottenere grapheme cluster # 69450 da un file di testo, allora devo eseguire una scansione lineare attraverso l'intero file e contare. Quindi le tue opzioni sono:

  • Costruisci un indice (tipo di pazzo ...)
  • Basta rendersi conto che non puoi rompere ogni limite di carattere. L'oggetto break iterator è in grado di andare avanti e indietro, quindi se hai bisogno di estrarre i primi 140 caratteri di una stringa, allora guardi l'indice 140 e iterate all'indietro alla precedente interruzione grapheme del cluster, in questo modo non finisci con un testo divertente. (Meglio ancora, puoi utilizzare un iteratore di word break per le impostazioni internazionali appropriate.) Il vantaggio dell'uso di questo livello di astrazione (iteratori di caratteri e simili) è che non importa più quale codifica usi: puoi usare UTF-8, UTF-16, UTF-32 e tutto funziona. Bene, per lo più funziona.
Question

Ho qualcosa come

a = "बिक्रम मेरो नाम हो"

Voglio ottenere qualcosa di simile

a[0] = बि a[1] = क्र a[3] = म

ma come म richiede 4 byte mentre बि impiega 8 byte, non sono in grado di arrivare a quella scala. Quindi cosa si potrebbe fare per ottenere ciò? In Python.




Gli script indicativi e non latini come Hangul generalmente non seguono l'idea di associare gli indici di stringa ai punti di codice. In genere è un problema lavorare con gli script Indic. La maggior parte dei personaggi sono due byte con alcuni rari che si estendono in tre. Con Dravidian, non è un ordine definito. Vedi le specifiche Unicode per maggiori dettagli.

Detto questo, controlla here alcune idee su unicode e python con C ++.

Infine, come ha affermato Dietrich , potresti voler controllare anche la ICU . Ha collegamenti disponibili per C / C ++ e java rispettivamente tramite icu4c e icu4j. C'è una certa curva di apprendimento, quindi ti suggerisco di dedicare un po ' di tempo a questo. :)






Related