【问题标题】:Regular Expressions in C# for Character EquivalentsC# 中用于字符等价的正则表达式
【发布时间】:2018-04-06 16:44:03
【问题描述】:

如何在 C# 中使用正则表达式搜索字符串,忽略重音符号;

例如在 Notepad++ 中,对于古希腊语,使用正则表达式搜索:[[=α=]] 将返回:α, ἀ ἁ, ᾶ, ὰ, ά, ᾳ, ....

我知道 Notepad++ 使用的是 PCRE 标准。 如何在 c# 中做到这一点?有等价语法吗?

编辑

我已经尝试过字符串规范化。不适用于希腊语。例如:“ᾶ”.Normalize(NormalizationForm.FormC) 将返回 ᾶ。看起来规范化仅在“组合字符”的情况下删除重音。 ᾶ 字符是 Unicode 中的一个单独字符!

【问题讨论】:

  • @ctwheels 不匹配所有希腊字母,而不仅仅是“a”的变体?
  • .NET 正则表达式不支持 POSIX 排序规则。首先规范化字符串或使用[αἀἁᾶὰάᾳ]之类的字符类
  • 已经尝试过标准化。请参阅已编辑的问题。看起来字符类是唯一的解决方案。会高效吗?仅对于字母 -α- 类将是 [ἀἁἂἃἄἅἆἇὰάᾀᾁᾂᾃᾄᾅᾆᾇᾰᾱᾲᾳᾴᾶᾷ]。搜索一个词会产生一个非常大的正则表达式。
  • @你试过normalization like this吗?因为当我在 上运行它时,我得到α

标签: c# .net regex


【解决方案1】:

System.String.Normalize 方法似乎仍然是解决这个问题的关键。

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Globalization;
using System.Linq;

public class Program
{
    public static void Main()
    {
        string rawInput = "ἀἁἂἃἄἅἆἇὰάᾀᾁᾂᾃᾄᾅᾆᾇᾰᾱᾲᾳᾴᾶᾷ";
        Console.WriteLine(rawInput);
        string normalizedInput = Utility.RemoveDiacritics(rawInput);    
        string pattern = "α+";

        var result = Regex.Matches(normalizedInput, pattern);
        if(result.Count > 0)
            Console.WriteLine(result[0]);    
    }
}

public static class Utility
{
    public static string RemoveDiacritics(this string str)
    {
        if (null == str) return null;
        var chars =
            from c in str.Normalize(NormalizationForm.FormD).ToCharArray()
            let uc = CharUnicodeInfo.GetUnicodeCategory(c)
            where uc != UnicodeCategory.NonSpacingMark
            select c;

        return new string(chars.ToArray()).Normalize(NormalizationForm.FormC);
    }
}

输出:

ἀἁἂἃἄἅἆἇὰάᾀᾁᾂᾃᾄᾅᾆᾇᾰᾱᾲᾳᾴᾶᾷᾶ
αααααααααααααααααααααααααα

Demo

卡普兰的原始方法:

static string RemoveDiacritics(string text) 
{
    var normalizedString = text.Normalize(NormalizationForm.FormD);
    var stringBuilder = new StringBuilder();        
    foreach (var c in normalizedString)
    {
        var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
        if (unicodeCategory != UnicodeCategory.NonSpacingMark)
        {
            stringBuilder.Append(c);
        }
    }       
    return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
}

参考资料:

PS:不幸的是,PCRE.NET,Lucas Trzesniewski 的 PCRE 库的 .NET 包装器不支持(扩展)POSIX 排序元素。

【讨论】:

  • 优秀的解决方案!是的,我已经测试过 PCRE.NET 并且不支持 POSIX 整理元素。
【解决方案2】:

【讨论】:

  • 我已经尝试过字符串规范化。不适用于希腊语。例如:“ᾶ”.Normalize(NormalizationForm.FormC) 将返回 ᾶ。看起来规范化仅在“组合字符”的情况下删除重音。还检查了第二个链接。看起来与我无关,因为它解决了大小写匹配问题!
猜你喜欢
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-08
  • 2011-08-24
  • 2012-06-19
  • 1970-01-01
相关资源
最近更新 更多