regex por aceptar solo caracteres persas

Estoy trabajando en un formulario en el que uno de los validadores personalizados solo debería aceptar caracteres persas … Utilicé el siguiente código:

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

pero parece que solo funciona para verificar caracteres árabes y no cubre todos los caracteres persas (carece de estos cuatro گ, چ, ژ). ¿Hay alguna manera de resolver este problema?

TL; DR

\u0600-\u06FF incluye:

  • 06AF con punto de código 06AF
  • چ con codepoint 0686
  • پ con codepoint 067E
  • ژ con codepoint 0698

también. No necesita preocuparse por چ پ ژ y duplicar los puntos de código (¡como en la respuesta aceptada !). Pero … todas las respuestas que dicen use \u0600-\u06FF o [آ-ی] son simplemente INCORRECTAS.

es decir, \u0600-\u06FF contiene 209 caracteres más de los que necesita. ¡e incluye números también!

enter image description here

Los conjuntos de caracteres usados ​​Farsi MUST son los siguientes:

  • Use ^[آابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی]+$ para letras o use puntos de código con respecto a su syntax de sabor:

     ^[\u0622\u0627\u0628\u067E\u062A-\u062C\u0686\u062D-\u0632\u0698\u0633-\u063A\u0641\u0642\u06A9\u06AF\u0644-\u0648\u06CC]+$ 
  • Use ^[۰۱۲۳۴۵۶۷۸۹]+$ para números o con respecto a su syntax de sabor:

     ^[\u06F0-\u06F9]+$ 
  • Use [ ‬ٌ ‬ًّ ‬َ ‬ِ ‬ُ ‬ْ ‬] para las vocales o con respecto a su syntax de sabor:

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

o una combinación de esos juntos. Es posible que desee agregar otras letras árabes como Hamza ء a su juego de caracteres adicionalmente.

Toda la historia

Esta respuesta existe para corregir un error común. Los puntos de código 0600 a 06FF no indican el alfabeto persa / farsi (tampoco lo hace [آ-ی] ):

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

255 caracteres están caídos bajo el bloque Árabe (0600-06FF), el alfabeto Farsi tiene 32 letras que además de la demostración Farsi de dígitos sería 42. Si agregamos vocales (vocales árabes originalmente, que rara vez se usan en Farsi) sin Tanvin ( ,, ٌ ‬ Y Tashdid ( ّ ‬ que son un subconjunto de signos diacríticos arábigos, no farsi, terminaríamos con 46 caracteres. Esto significa que \u0600-\u06FF contiene 209 caracteres más de los que necesita.

۷ con codepoint 06F7 es una representación farsi de los números 7 y ٧ con codepoint 0667 es la representación árabe del mismo número. ۶ es la representación farsi del número 6 y ٦ es la representación árabe del mismo número. Y todos residen en los 06FF código 0600 a 06FF .

Las formas de los dígitos persas cuatro ( ۴ ), cinco ( ۵ ) y seis ( ۶ ) son diferentes de las formas utilizadas en árabe y los otros números tienen diferentes puntos de código.

También puede ver una cantidad diferente de otros caracteres que no existen en persa / farsi y nadie está dispuesto a tenerlos mientras valida un nombre o apellido.

[آ-ی] incluye 117 caracteres, que es mucho más de lo que alguien necesita para la validación. Puede verlos todos usando Unicode CLDR .

Lo que tienes actualmente en tu expresión regular es un rango estándar de símbolos arábigos . Para caracteres adicionales su necesidad de agregarlos a la expresión regular por separado. Aquí están sus códigos:

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

Entonces, en general, deberías tener

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

Además de la respuesta aceptada ( https://stackoverflow.com/a/22565376/790811 ), también deberíamos considerar caracteres Zero-width_non-joiner (o نیم فاصله en persa). Desafortunadamente tenemos 2 símbolos para eso. Uno es estándar y el otro no es estándar, pero se usa ampliamente:

  1. C: http://en.wikipedia.org/wiki/Zero-width_non-joinero
  2. F: marca de derecha a izquierda ( http://unicode-table.com/en/#200F )

Entonces el regix final puede ser:

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

Si desea considerar el ” espacio “, puede usar esto:

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

usted puede probarlo JavaScript con esto:

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

atención: persianRex está escrito en Javascript; sin embargo, puede usar el código fuente y copiar pegar los caracteres

La detección de caracteres persas es una tarea difícil debido a la variedad de diseños de teclado y sistemas operativos. Me enfrenté al mismo desafío en algún momento antes y decidí escribir una biblioteca de código abierto para solucionar este problema.

puede solucionar su problema de esta manera: persianRex.text.test (yourInput); // devuelve verdadero o falso

aquí está la documentación completa: http://imanmh.github.io/persianRex/

Farsi, Dari y Tajik están fuera de mi bailía, pero un poco rebuscando en los gráficos de códigos Unicode me dice que el árabe cubre 5 bloques de código Unicode:

Puede obtenerlos (al menos algunos de ellos) en expresiones regulares usando bloques con nombre en lugar de rangos de puntos de código explícitos: \p{IsArabicPresentationForms-A} le dará el 4 ° bloque Unicode en la lista anterior.

También puede leer Persian Computing en Unicode: http://behdad.org/download/Publications/persiancomputing/a007.pdf

No puedo leer Farsi pero veo si uno de los suplementos árabes Unicode tiene las letras que estás buscando.

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

Los bloques nombrados, por ejemplo, \ p {Arabic}, cubren toda la secuencia de comandos árabe , no solo los caracteres persas.

Los formularios de presentación (u + FB50-u + FDFF) no se deben usar en el texto, y se deben convertir al rango estándar (u + 0600-u + 06FF).

Para cubrir solo persa, necesitamos lo siguiente:

  • El subconjunto de caracteres Farsi fuera del rango árabe estándar, es decir (U + 0621-U + 0624, U + 0626-U + 063A, U + 0641-U + 0642, U + 0644-U + 0648)
  • Los signos diacríticos árabes estándar (U + 064B-U + 0652)
  • Los 2 signos diacríticos adicionales (U + 0654, U + 0670)
  • Los 4 caracteres extrafarsianos “گ چ پ (” (U + 067E, U + 0686, U + 0698, U + 06AF)
  • U + 06A9: Kaf persa (formalmente: “Letra árabe Keheh”; notación diferente del árabe Kaf)
  • U + 06CC: Farsi Yeh (una notación diferente del árabe Yeh)
  • U + 200C: Zero-Width-Non-Joiner

Entonces, la expresión regular resultante sería:

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

Vea también los ejemplos de caracteres para persa listados aquí:

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

No estoy seguro de si la expresión regular es la forma de hacerlo, sin embargo, el problema no es específico solo para el texto en persa o árabe, chino o ruso. así que quizás puedas ver si el personaje está en tu página de códigos, si no está en la página de códigos, entonces dudo que el usuario pueda insertarlos usando un dispositivo de entrada ….

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

La prueba prueba un viaje de ida y vuelta donde la entrada debe coincidir con la cadena en bytes y viceversa. El enlace muestra esas páginas de códigos compatibles.