Удалить диакритические знаки, за исключением определенных диакритических знаков на определенных буквах - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь удалить ивритские диакритические знаки.Мне нужно убрать все диакритические знаки, кроме указанных диакритических знаков, следующих за данными буквами.

Это мой нерабочий RemoveDiacritics (см. скрипка ):

public static string RemoveDiacritics(Dictionary<char, char[]> exclude, string source)
{
    // Exclude letters (using a lookbehind), include diacritics
    string match = "(?<=[א-ת])[\u05b0-\u05c2]";    

    // Prepare the exclusion group
    string exclusionGroup = string.Join("|", exclude.Select(p => 
         string.Concat(p.Key, string.Join(string.Empty, p.Value)))
    );

    // Create the exclusion group (using a lookahead)
    string except = $"(?!{exclusionGroup})";

    // Do the match
    return Regex.Replace(source, string.Concat(except, match), string.Empty);
}

Я проверил это с:

static void Main(string[] args)
{
    string source = "חָזִיתִי כְּמִבַּעַד לֶעָשָׁן בְּקִמּוּרֵי הָרֶסֶס הַלָּבָן";
    Dictionary<char, char[]> exclude = new Dictionary<char, char[]>
    {
        {'\u05db', new char[] {'\u05bc' } }, // כּ
        {'\u05d1', new char[] {'\u05bc', '\u05b7' } }, // בַּ
    };
    string replaced = RemoveDiacritics(exclude, source);
}

Ожидаетсярезультат: "חזיתי כּמבַּעד לעשן בקמורי הרסס הלבן" (только 2 буквы во втором слове должны иметь диакритические знаки).

Фактический результат: "חזיתי כְמִבַעד לעשָן בְקמורי הרסס הלָבן"

В моем реальном результате вы можете видеть, что:

  1. Любая буква, у которой '\u05bc' (это маленькая точка внутри буквы) вместе с дополнительным диакритическим знаком, ошибочно оставляется с этим дополнительным диакритическим знаком.

  2. Кроме того, на מִ и שָ остались диакритические знаки (они находятся на 2-м и 3-м слове соответственно).Понятия не имею, почему.

Как я могу заставить его работать?

1 Ответ

0 голосов
/ 27 сентября 2018

Ваш RemoveDiacritics метод должен выглядеть следующим образом:

public static string RemoveDiacritics(Dictionary<char, char[]> exclude, string source)
{
    string exclusionGroup = string.Join("|", exclude.Select(p => string.Concat(p.Key, string.Join(string.Empty, p.Value))));
    string leaveOnly = String.Concat(String.Format(@"({0})|\p{{M}}+", exclusionGroup));
    return Regex.Replace(source, leaveOnly, "$1");
}

Что он делает:

  • exclusionGroup создается из символов exclude, и это простопоследовательность чередования
  • leaveOnly является шаблоном регулярного выражения, его форма соответствует (<what_you_need_to_keep>)|\p{M}+, а захватывает то, что вам нужно сохранить (игнорировать) в группе 1, и просто соответствует любым диакритическим знакам 1+используя шаблон \p{M}+.
  • Шаблон замены является держателем значения группы 1 $1, чтобы восстановить его в результирующей строке.

Вот онлайн C # демо .

...