首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何比较“看起来相似”的Unicode字符?

如何比较“看起来相似”的Unicode字符?
EN

Stack Overflow用户
提问于 2018-03-30 06:04:12
回答 2查看 0关注 0票数 0

我陷入了一个令人惊讶的问题。

我在我的应用程序中加载了一个文本文件,并且我有一些逻辑来比较具有μ的值。

而且我意识到即使文本相同,比较值也是错误的。

代码语言:javascript
复制
 Console.WriteLine("μ".Equals("µ")); // returns false
 Console.WriteLine("µ".Equals("µ")); // return true

在后面的行中,字符μ被复制粘贴。

但是,这些可能不是唯一的字符。

在C#中有什么方法比较看起来相同但实际上不同的字符?

EN

回答 2

Stack Overflow用户

发布于 2018-03-30 14:24:53

在很多情况下,你可以正常化比较之前两个Unicode字符的一定范式,他们应该能够匹配。当然,你需要使用哪种规范化表单取决于字符本身; 只是因为它们看起来相似并不一定意味着它们代表相同的性格。您还需要考虑它是否适合您的用例 - 请参阅Jukka K. Korpela的评论。

对于这种特殊情况,如果你参考Tony的答案中的链接,你会发现U + 00B5的表格说:

分解<compat>希腊小字母MU(U + 03BC)

这意味着U + 00B5,原始比较中的第二个字符,可以分解为U + 03BC,第一个字符。

因此,您将使用完全兼容性分解对字符进行规范化处理,使用标准化表单KC或KD。下面是我写下的一个快速示例:

代码语言:javascript
复制
using System;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        char first = 'μ';
        char second = 'µ';

        // Technically you only need to normalize U+00B5 to obtain U+03BC, but
        // if you're unsure which character is which, you can safely normalize both
        string firstNormalized = first.ToString().Normalize(NormalizationForm.FormKD);
        string secondNormalized = second.ToString().Normalize(NormalizationForm.FormKD);

        Console.WriteLine(first.Equals(second));                     // False
        Console.WriteLine(firstNormalized.Equals(secondNormalized)); // True
    }
}

有关Unicode正常化细节和不同的标准化形式是指System.Text.NormalizationFormUnicode的规范

票数 0
EN

Stack Overflow用户

发布于 2018-03-30 15:07:36

因为它们看起来是完全不同的符号,它们看起来是一样的,首先是实际的字母,并且有字符code = 956 (0x3BC),第二个是微型符号,并且具有181 (0xB5)

参考文献:

因此,如果您想比较它们并且需要它们相等,则需要手动处理它,或者在比较之前将其替换为另一个字符。或者使用下面的代码:

代码语言:javascript
复制
public void Main()
{
    var s1 = "μ";
    var s2 = "µ";

    Console.WriteLine(s1.Equals(s2));  // false
    Console.WriteLine(RemoveDiacritics(s1).Equals(RemoveDiacritics(s2))); // true 
}

static string RemoveDiacritics(string text) 
{
    var normalizedString = text.Normalize(NormalizationForm.FormKC);
    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);
}

演示

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100004330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档