Cómo detectar si un personaje pertenece a un idioma de derecha a izquierda?
-
30-09-2019 - |
Pregunta
¿Qué es una buena manera de saber si una cadena contiene texto en un idioma Izquierda Derecha A.
He encontrado que esto pregunta que sugiere el siguiente enfoque:
public bool IsArabic(string strCompare)
{
char[] chars = strCompare.ToCharArray();
foreach (char ch in chars)
if (ch >= '\u0627' && ch <= '\u0649') return true;
return false;
}
Si bien esto puede funcionar para árabe, esto no parece para cubrir otros idiomas RTL como el hebreo. ¿Hay una manera genérica para saber que un personaje en particular pertenece a un lenguaje RTL?
Solución
caracteres Unicode tienen diferentes propiedades asociadas con ellos. Estas propiedades no se pueden derivar del punto de código; también necesita una tabla que le indica si un personaje tiene una cierta propiedad o no.
Usted está interesado en caracteres con bienes bidireccional "R" o "AL" (RandALCat).
Un carácter RandALCat es un personaje con direccionalidad sin ambigüedad de derecha a izquierda.
Esta es la lista completa de Unicode 3.2 (de RFC 3454 ):
D. Bidirectional tables D.1 Characters with bidirectional property "R" or "AL" ----- Start Table D.1 ----- 05BE 05C0 05C3 05D0-05EA 05F0-05F4 061B 061F 0621-063A 0640-064A 066D-066F 0671-06D5 06DD 06E5-06E6 06FA-06FE 0700-070D 0710 0712-072C 0780-07A5 07B1 200F FB1D FB1F-FB28 FB2A-FB36 FB38-FB3C FB3E FB40-FB41 FB43-FB44 FB46-FBB1 FBD3-FD3D FD50-FD8F FD92-FDC7 FDF0-FDFC FE70-FE74 FE76-FEFC ----- End Table D.1 -----
Aquí hay un código para obtener la lista completa de Unicode 6.0:
var url = "http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt";
var query = from record in new WebClient().DownloadString(url).Split('\n')
where !string.IsNullOrEmpty(record)
let properties = record.Split(';')
where properties[4] == "R" || properties[4] == "AL"
select int.Parse(properties[0], NumberStyles.AllowHexSpecifier);
foreach (var codepoint in query)
{
Console.WriteLine(codepoint.ToString("X4"));
}
Tenga en cuenta que estos valores son los puntos de código Unicode. Las cadenas en C # /. NET son UTF-16 codificado y deben ser convertidos a Unicode puntos de código primero (ver Char.ConvertToUtf32 ). He aquí un método que comprueba si una cadena contiene al menos un carácter RandALCat:
static void IsAnyCharacterRightToLeft(string s)
{
for (var i = 0; i < s.Length; i += char.IsSurrogatePair(s, i) ? 2 : 1)
{
var codepoint = char.ConvertToUtf32(s, i);
if (IsRandALCat(codepoint))
{
return true;
}
}
return false;
}
Otros consejos
Puede intentar usar " bloques nombrados " en regular . Apenas seleccione los bloques que son de derecha a izquierda, y formar la expresión regular. Por ejemplo:
\p{IsArabic}|\p{IsHebrew}
Si que los rendimientos de expresiones regulares cierto, entonces no era por lo menos un hebreo o árabe carácter en la cadena.
All "AL" o "R" de Unicode 6.0 (de http: // www. unicode.org/Public/6.0.0/ucd/UnicodeData.txt )
bool hasRandALCat = 0;
if(c >= 0x5BE && c <= 0x10B7F)
{
if(c <= 0x85E)
{
if(c == 0x5BE) hasRandALCat = 1;
else if(c == 0x5C0) hasRandALCat = 1;
else if(c == 0x5C3) hasRandALCat = 1;
else if(c == 0x5C6) hasRandALCat = 1;
else if(0x5D0 <= c && c <= 0x5EA) hasRandALCat = 1;
else if(0x5F0 <= c && c <= 0x5F4) hasRandALCat = 1;
else if(c == 0x608) hasRandALCat = 1;
else if(c == 0x60B) hasRandALCat = 1;
else if(c == 0x60D) hasRandALCat = 1;
else if(c == 0x61B) hasRandALCat = 1;
else if(0x61E <= c && c <= 0x64A) hasRandALCat = 1;
else if(0x66D <= c && c <= 0x66F) hasRandALCat = 1;
else if(0x671 <= c && c <= 0x6D5) hasRandALCat = 1;
else if(0x6E5 <= c && c <= 0x6E6) hasRandALCat = 1;
else if(0x6EE <= c && c <= 0x6EF) hasRandALCat = 1;
else if(0x6FA <= c && c <= 0x70D) hasRandALCat = 1;
else if(c == 0x710) hasRandALCat = 1;
else if(0x712 <= c && c <= 0x72F) hasRandALCat = 1;
else if(0x74D <= c && c <= 0x7A5) hasRandALCat = 1;
else if(c == 0x7B1) hasRandALCat = 1;
else if(0x7C0 <= c && c <= 0x7EA) hasRandALCat = 1;
else if(0x7F4 <= c && c <= 0x7F5) hasRandALCat = 1;
else if(c == 0x7FA) hasRandALCat = 1;
else if(0x800 <= c && c <= 0x815) hasRandALCat = 1;
else if(c == 0x81A) hasRandALCat = 1;
else if(c == 0x824) hasRandALCat = 1;
else if(c == 0x828) hasRandALCat = 1;
else if(0x830 <= c && c <= 0x83E) hasRandALCat = 1;
else if(0x840 <= c && c <= 0x858) hasRandALCat = 1;
else if(c == 0x85E) hasRandALCat = 1;
}
else if(c == 0x200F) hasRandALCat = 1;
else if(c >= 0xFB1D)
{
if(c == 0xFB1D) hasRandALCat = 1;
else if(0xFB1F <= c && c <= 0xFB28) hasRandALCat = 1;
else if(0xFB2A <= c && c <= 0xFB36) hasRandALCat = 1;
else if(0xFB38 <= c && c <= 0xFB3C) hasRandALCat = 1;
else if(c == 0xFB3E) hasRandALCat = 1;
else if(0xFB40 <= c && c <= 0xFB41) hasRandALCat = 1;
else if(0xFB43 <= c && c <= 0xFB44) hasRandALCat = 1;
else if(0xFB46 <= c && c <= 0xFBC1) hasRandALCat = 1;
else if(0xFBD3 <= c && c <= 0xFD3D) hasRandALCat = 1;
else if(0xFD50 <= c && c <= 0xFD8F) hasRandALCat = 1;
else if(0xFD92 <= c && c <= 0xFDC7) hasRandALCat = 1;
else if(0xFDF0 <= c && c <= 0xFDFC) hasRandALCat = 1;
else if(0xFE70 <= c && c <= 0xFE74) hasRandALCat = 1;
else if(0xFE76 <= c && c <= 0xFEFC) hasRandALCat = 1;
else if(0x10800 <= c && c <= 0x10805) hasRandALCat = 1;
else if(c == 0x10808) hasRandALCat = 1;
else if(0x1080A <= c && c <= 0x10835) hasRandALCat = 1;
else if(0x10837 <= c && c <= 0x10838) hasRandALCat = 1;
else if(c == 0x1083C) hasRandALCat = 1;
else if(0x1083F <= c && c <= 0x10855) hasRandALCat = 1;
else if(0x10857 <= c && c <= 0x1085F) hasRandALCat = 1;
else if(0x10900 <= c && c <= 0x1091B) hasRandALCat = 1;
else if(0x10920 <= c && c <= 0x10939) hasRandALCat = 1;
else if(c == 0x1093F) hasRandALCat = 1;
else if(c == 0x10A00) hasRandALCat = 1;
else if(0x10A10 <= c && c <= 0x10A13) hasRandALCat = 1;
else if(0x10A15 <= c && c <= 0x10A17) hasRandALCat = 1;
else if(0x10A19 <= c && c <= 0x10A33) hasRandALCat = 1;
else if(0x10A40 <= c && c <= 0x10A47) hasRandALCat = 1;
else if(0x10A50 <= c && c <= 0x10A58) hasRandALCat = 1;
else if(0x10A60 <= c && c <= 0x10A7F) hasRandALCat = 1;
else if(0x10B00 <= c && c <= 0x10B35) hasRandALCat = 1;
else if(0x10B40 <= c && c <= 0x10B55) hasRandALCat = 1;
else if(0x10B58 <= c && c <= 0x10B72) hasRandALCat = 1;
else if(0x10B78 <= c && c <= 0x10B7F) hasRandALCat = 1;
}
}
EDIT:
Esto es lo que uso ahora, que incluye los caracteres Vowelization y todo en hebreo y árabe:
[\u0591-\u07FF]
vieja respuesta:
Si necesita detectar el lenguaje RTL en una frase, esta expresión regular simplificada probablemente será suficiente:
[א-ת-ۿ]
Si uno quiere escribir algo en hebreo que se tienen que utilizar uno de estos personajes, y el caso es similar con el árabe.
No incluye caracteres vowelization, así que si usted necesita coger todas las palabras enteras o absolutamente todos los caracteres RTL le mejor utilizar una de las otras respuestas. Vowelization caracteres en hebreo son muy raros en los textos no poesía. No sé sobre textos árabes.