删除变音符号,但某些字母上的变音符号除外

时间:2018-09-27 15:55:52

标签: c# regex regex-lookarounds diacritics

我正在尝试删除希伯来语变音符号。除了给定的变音符,我需要删除所有给定字母之后的变音符。

这是我无法工作的RemoveDiacritics(请参阅fiddle):

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. 此外,מִשָ上还有变音符号(分别位于第二和第三个单词上)。不知道为什么。

我如何使其工作?

1 个答案:

答案 0 :(得分:2)

您的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的所有者,用于将其恢复为结果字符串。

这里是online C# demo