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.





bidi