regex per accettare solo caratteri persiani

Sto lavorando su un modulo che uno dei suoi validatori personalizzati dovrebbe accettare solo caratteri persiani … Ho usato il seguente codice:

var myregex = new Regex(@"^[\u0600-\u06FF]+$"); if (myregex.IsMatch(mytextBox.Text)) { args.IsValid = true; } else { args.IsValid = false; } 

ma sembra funzionare solo per il controllo dei caratteri arabi e non copre tutti i caratteri persiani (manca questi quattro گ, چ, پ, ژ) … c’è un modo per risolvere questo problema?

TL; DR

\u0600-\u06FF include:

  • گ con 06AF
  • چ con il 0686
  • پ con il punto 067E
  • ژ con il 0698

anche. Non devi preoccuparti di گ چ پ ژ e duplicare i ژ (come nella risposta accettata !). Ma … tutte le risposte che dicono usare \u0600-\u06FF o [آ-ی] sono semplicemente SBAGLIATE.

cioè \u0600-\u06FF contiene 209 caratteri in più del necessario! e include anche i numeri!

inserisci la descrizione dell'immagine qui

I set di caratteri usati MUST devono essere i seguenti:

  • Usa ^[آابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی]+$ per lettere o usando i codepoint relativi alla tua syntax di sapore:

     ^[\u0622\u0627\u0628\u067E\u062A-\u062C\u0686\u062D-\u0632\u0698\u0633-\u063A\u0641\u0642\u06A9\u06AF\u0644-\u0648\u06CC]+$ 
  • Utilizza ^[۰۱۲۳۴۵۶۷۸۹]+$ per i numeri o per quanto riguarda la syntax del sapore:

     ^[\u06F0-\u06F9]+$ 
  • Usa [ ‬ٌ ‬ًّ ‬َ ‬ِ ‬ُ ‬ْ ‬] per le vocali o per quanto riguarda la syntax del tuo gusto:

     [\u202C\u064B\u064C\u064E-\u0652] 

o una combinazione di quelli insieme. Potresti aggiungere altre lettere arabe come Hamza ء al tuo set di caratteri in aggiunta.

L’intera storia

Questa risposta esiste per correggere un malinteso comune. I codici dei punti da 0600 a 06FF non indicano l’alfabeto persiano / farsi (nemmeno [آ-ی] ):

 [\u0600-\u0605 ؐ-ؚ\u061Cـ ۖ-\u06DD ۟-ۤ ۧ ۨ ۪-ۭ ً-ٕ ٟ ٖ-ٞ ٰ ، ؍ ٫ ٬ ؛ ؞ ؟ ۔ ٭ ٪ ؉ ؊ ؈ ؎ ؏ ۞ ۩ ؆ ؇ ؋ ٠۰ ١۱ ٢۲ ٣۳ ٤۴ ٥۵ ٦۶ ٧۷ ٨۸ ٩۹ ءٴ۽ آ أ ٲ ٱ ؤ إ ٳ ئ ا ٵ ٮ ب ٻ پ ڀ ة-ث ٹ ٺ ټ ٽ ٿ ج ڃ ڄ چ ڿ ڇ ح خ ځ ڂ څ د ذ ڈ-ڐ ۮ ر ز ڑ-ڙ ۯ س ش ښ-ڜ ۺ ص ض ڝ ڞ ۻ ط ظ ڟ ع غ ڠ ۼ ف ڡ-ڦ ٯ ق ڧ ڨ ك ک-ڴ ػ ؼ ل ڵ-ڸ م۾ ن ں-ڽ ڹ ه ھ ہ-ۃ ۿ ەۀ وۥ ٶ ۄ-ۇ ٷ ۈ-ۋ ۏ ى يۦ ٸ ی-ێ ې ۑ ؽ-ؿ ؠ ے ۓ \u061D] 

255 caratteri sono caduti sotto il blocco arabo (0600-06FF), l’alfabeto Farsi ha 32 lettere che oltre alla dimostrazione Farsi di cifre sarebbe 42. Se aggiungiamo le vocali (in origine le vocali arabe, che raramente sono usate in farsi) senza Tanvin ( ,, ٌ ‬ E Tashdid ( ّ ‬ che sono entrambi un sottogruppo di segni diacritici arabi non Farsi, avremmo finito con 46 caratteri. Ciò significa che \u0600-\u06FF contiene 209 caratteri in più del necessario!

۷ con il 06F7 è una rappresentazione Farsi del numero 7 e ٧ con il 0667 è la rappresentazione araba dello stesso numero. ۶ è la rappresentazione Farsi del numero 6 e ٦ è la rappresentazione araba dello stesso numero. E tutti risiedono tra i 06FF 0600 e 06FF .

Le forms delle cifre persiane quattro ( ۴ ), cinque ( ۵ ) e sei ( ۶ ) sono diverse dalle forms utilizzate in arabo e gli altri numeri hanno codepoint diversi.

Puoi vedere un numero diverso di altri personaggi che non esiste in Persiano / Persiano e nessuno è disposto ad averli durante la convalida di un nome o di un cognome.

[آ-ی] include anche 117 caratteri, che è molto più di quello che qualcuno ha bisogno per la convalida. Puoi vederli tutti usando Unicode CLDR .

Quello che hai attualmente nella tua espressione regolare è una gamma di simboli arabi standard . Per i personaggi aggiuntivi è necessario aggiungerli separatamente alla regex. Ecco i loro codici:

 ژ \u0698 پ \u067E چ \u0686 گ \u06AF 

Quindi tutto sumto dovresti avere

 ^[\u0600-\u06FF\u0698\u067E\u0686\u06AF]+$ 

Oltre alla risposta accettata ( https://stackoverflow.com/a/22565376/790811 ), dovremmo considerare anche i caratteri Zero-width_non-joiner (o نیم فاصله in persiano). Sfortunatamente abbiamo 2 simboli per questo. Uno è standard e l’altro non è standard ma ampiamente utilizzato:

  1. \ u200C: http://en.wikipedia.org/wiki/Zero-width_non-joiner
  2. \ F: segno da destra a sinistra ( http://unicode-table.com/en/#200F )

Quindi la regix finale può essere:

 ^[\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\u200F]+$ 

Se vuoi considerare lo ” spazio “, puoi usare questo:

 ^[\u0600-\u06FF\uFB8A\u067E\u0686\u06AF\u200C\u200F ]+$ 

puoi testarlo in questo modo:

 /^[\u0600-\u06FF\uFB8A\u067E\u0686\u06AF7\u200C\u200F ]+$/.test('ای‌پسر تو چه می‌دانی؟') 

attenzione: persianRex è scritto in Javascript, tuttavia è ansible utilizzare il codice sorgente e copiare i caratteri incollati

Rilevare i caratteri persiani è un compito difficile a causa della moltitudine di layout di tastiera e sistemi operativi. Ho affrontato la stessa sfida qualche tempo prima e ho deciso di scrivere una libreria open source per risolvere questo problema.

puoi risolvere il tuo problema in questo modo: persianRex.text.test (yourInput); // restituisce vero o falso

ecco la documentazione completa: http://imanmh.github.io/persianRex/

Farsi, Dari e Tajik sono fuori dal mio baliato, ma un po ‘rovistando tra le tabelle dei codici Unicode mi dice che l’arabo copre 5 blocchi di codice Unicode:

Puoi ottenerli (almeno alcuni di essi) in espressioni regolari usando blocchi denominati invece di intervalli di punti di codice espliciti: \p{IsArabicPresentationForms-A} ti darà il 4 ° blocco Unicode nell’elenco precedente.

Potresti anche leggere il Persian Computing in Unicode: http://behdad.org/download/Publications/persiancomputing/a007.pdf

Non riesco a leggere Farsi ma vedo se uno dei supplementi in arabo unicode ha le lettere che stai cercando.

http://www.unicode.org/charts/

I blocchi nominati, ad esempio \ p {arabo} coprono l’intera scrittura araba , non solo i caratteri persiani.

I moduli di presentazione (u + FB50 -u + FDFF) non devono essere utilizzati nel testo e devono essere convertiti nell’intervallo standard (u + 0600-u + 06FF).

Per coprire solo il Persiano, abbiamo bisogno di quanto segue:

  • Il sottoinsieme di caratteri Farsi fuori dalla gamma standard araba, cioè (U + 0621-U + 0624, U + 0626-U + 063A, U + 0641-U + 0642, U + 0644-U + 0648)
  • I segni diacritici arabi standard (U + 064B-U + 0652)
  • I 2 segni diacritici aggiuntivi (U + 0654, U + 0670)
  • I 4 caratteri Farsi in più “گ چ پ ژ” (U + 067E, U + 0686, U + 0698, U + 06AF)
  • U + 06A9: Persiano Kaf (formalmente: “Arabic Letter Keheh”; notazione diversa dall’arabo Kaf)
  • U + 06CC: Farsi Yeh (una notazione diversa dall’arabo Yeh)
  • U + 200C: Zero-Width-Non-Joiner

Quindi, la regexp risultante sarebbe:

 ^[\u0621-\u0624\u0626-\u063A\u0641-\u0642\u0644-\u0648\u064B-\u0652\u067E\u0686\u0698\u06AF\u06CC\u06A9\u0654\u670\u200c}]+$ 

Vedi anche i caratteri dell’esempio per il persiano elencati qui:

http://unicode.org/cldr/trac/browser/trunk/common/main/fa.xml

Non sono sicuro che la regex sia il modo per farlo, tuttavia il problema non è specifico solo per persiano o arabo, cinese, testo russo. quindi forse potresti vedere se il personaggio è presente nella tua Codepage , se non nella code page allora dubito che l’utente possa inserirli usando un dispositivo di input ….

  var encoding = Encoding.GetEncoding(1256); var expect = "گ چ پ ژ"; var actual= encoding.GetBytes("گ چ پ ژ"); Assert.AreEqual(encoding.GetString(actual),expect); 

Il test verifica un round trip in cui l’input deve corrispondere alla stringa in byte e viceversa. Il collegamento mostra quelle code page supportate.