去除变音符号,但某些字母上的特定变音符号除外

3

我试图去除希伯来文变音符号。我需要删除所有变音符号,但排除在给定字母后出现的指定变音符号。

这是我的不起作用的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. 此外,מִשָ上保留了变音符号(它们分别位于第二个和第三个单词)。不知道为什么。

如何使其正常工作?


作为第一步,我会调试输出“exclusionGroup”的运行时值,并测试生成的正则表达式。 - Cee McSharpface
@dlatikay,我得到了预期的结果,即(?!כּ|בַּ),这正是我需要的(或者不是吗?)。 - OfirD
你的意思是想删除所有的变音符号,但在某些字母后面保留一些吗? - Wiktor Stribiżew
@Wiktor Stribiżew,没错。 - OfirD
然后,尝试使用类似 @"(what_you_need_to_keep)|\p{M}+" 的表达式,并替换为 $1 - Wiktor Stribiżew
显示剩余4条评论
1个回答

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 组,并使用 \p{M}+ 模式匹配任何 1 个或多个变音符号。
  • 替换模式是占位符 Group 1 值 $1,将其恢复到结果字符串中。

这里有一个 在线 C# 演示


据我所理解,它没有匹配所有的变音符号,并且负向先行断言和正向后行断言在字符串内的同一位置被执行。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接