c# - Come rilevare se un personaggio appartiene a una lingua da destra a sinistra?
localization right-to-left (3)
I caratteri Unicode hanno proprietà diverse associate ad essi. Queste proprietà non possono essere derivate dal punto di codice; hai bisogno di una tabella che ti dice se un personaggio ha una certa proprietà o no.
Ti interessano i caratteri con proprietà bidirezionali "R" o "AL" (RandALCat).
Un personaggio di RandALCat è un personaggio con una direzionalità da destra a sinistra inequivocabile.
Ecco l'elenco completo di Unicode 3.2 (da 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 -----
Ecco un codice per ottenere l'elenco completo a partire da 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"));
}
Si noti che questi valori sono punti di codice Unicode. Le stringhe in C # /. NET sono codificate in UTF-16 e devono essere convertite prima in punti codice Unicode (vedere Char.ConvertToUtf32 ). Ecco un metodo che controlla se una stringa contiene almeno un carattere 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;
}
Qual è un buon modo per dire se una stringa contiene del testo in una lingua da destra a sinistra.
Ho trovato questa question che suggerisce il seguente approccio:
public bool IsArabic(string strCompare)
{
char[] chars = strCompare.ToCharArray();
foreach (char ch in chars)
if (ch >= '\u0627' && ch <= '\u0649') return true;
return false;
}
Anche se questo potrebbe funzionare per l'arabo, questo non sembra coprire altri linguaggi RTL come l'ebraico. Esiste un modo generico per sapere che un determinato personaggio appartiene a un linguaggio RTL?
Puoi provare a usare " named blocks " nelle espressioni regolari . Basta selezionare i blocchi da destra a sinistra e formare la regex. Per esempio:
\p{IsArabic}|\p{IsHebrew}
Se tale regex restituisce true, allora nella stringa c'era almeno un carattere ebraico o arabo.
MODIFICARE:
Questo è quello che uso ora, include i caratteri di Vowelization e tutto in ebraico e arabo:
[\u0591-\u07FF]
VECCHIA RISPOSTA:
Se è necessario rilevare la lingua RTL in una frase, questo RegEx semplificato sarà probabilmente sufficiente:
[א-ת-ۿ]
Se uno vuole scrivere qualcosa in ebraico dovrà usare uno di questi personaggi, e il caso è simile all'arabo.
Non include i caratteri di vowelization, quindi se è necessario catturare tutte le parole intere o assolutamente tutti i caratteri RTL è meglio usare una delle altre risposte. I caratteri di vocalizzazione in ebraico sono molto rari nei testi di non poesia. Non so sui testi arabi.