首页 > 解决方案 > c# 比较字符串不考虑语言

问题描述

我有一个例程试图在字符串列表中查找特定术语。

int FindString(string term, List<string> stringList)
{
    for (int i = 0; i < stringList.Count; i++)
    {
        if (stringList[i].Contains(term))
        {
            return i;
        }
    }

    return -1;
}

该术语始终是英语中的 Unicode 字符串——例如“B4”——而字符串列表包含可以用其他语言编写的字符串。例如,一个字符串可能包含“B4”,但由于它是用希腊语编写的,因此在比较基本相同字符的英语和希腊语版本时,Contains 方法返回 false。

有没有办法转换非英语字符串,以便 Contains 方法正确返回 true?

示例术语和字符串(实际的文件名):

term: B4

string: 19-299-12-Β4.txt

标签: c#string

解决方案


基本上,您需要根据您的自定义规则“规范化”字符串,而不是执行搜索。

由于没有普遍接受的映射至少包含“拉丁 B”等于“希腊 B”,因此您必须构建自己的 - 基本字典Dictionary<char,char>可能就足够了。

作为“规范化”的一部分,您还可以考虑数字映射 - 因为实际上有官方 Unicode 信息可用 - GetDigitValue

因此,要规范化的整体代码如下所示:

var source = "А9"; // Cyrilic A9 - "\u0410\u0039"
var map = new Dictionary<char,char> { { 'А', 'A' } }; // Cyrillic to Latin 
var chars = source.Select( c =>
     CharUnicodeInfo.GetUnicodeCategory(c)==UnicodeCategory.DecimalDigitNumber?
           CharUnicodeInfo.GetDigitValue(c).ToString()[0] :
     map.ContainsKey(c) ? map[c] : 
     c);
var result = String.Join("", chars);

var term = "\u0041\u0039"; // Latin A9
Console.WriteLine(source.Contains(term));       
Console.WriteLine(result.Contains(term));

推荐阅读