代码之家  ›  专栏  ›  技术社区  ›  OfirD

去掉音调符号,除了某些字母上的某些音调符号

  •  3
  • OfirD  · 技术社区  · 6 年前

    这是我的业余爱好 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);
    }
    

    "חזיתי כּמבַּעד לעשן בקמורי הרסס הלבן" (第二个单词上只有两个字母应该有变音符号)。

    "חזיתי כְמִבַעד לעשָן בְקמורי הרסס הלָבן"

    在我的实际结果中,你可以看到:

    1. 任何一封信 '\u05bc' 里面 一个字母)和一个附加的变音符号一起,被错误地用那个附加的变音符号留下。

    2. מִ שָ (他们在2号&分别是第三个单词)。不知道为什么。

    我该怎么做?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Wiktor Stribiżew    6 年前

    你的 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}+
    • 替换模式是palceholder到Group 1的值, $1 ,将其还原到结果字符串中。

    这是一个 online C# demo