比较非英文字符的字符串

本文关键字:字符 字符串 文字符 比较 | 更新日期: 2023-09-27 17:48:58

我需要比较一个网站上的搜索机制的字符串。我使用c#。我试了两种方法:

consultants.Where(x => 
    x.Description.ToLower().Contains(vm.Description.ToLower()));

consultants.Where(x => 
    Regex.IsMatch(x.Description, vm.Description, RegexOptions.IgnoreCase));

都适用于所有英文字符。所以如果我搜索,比如说,"english",这没有问题。但是,当我尝试搜索包含非英语字符的字符串时,它就不起作用了。例如,如果我尝试搜索单词"spramatk"(瑞典语中的"语言"),它将一无所获。

这是为什么,我该如何解决它?

比较非英文字符的字符串

使用

String.Equals(c, vm, StringComparison.OrdinalIgnoreCase)

c.IndexOf(vm, StringComparison.OrdinalIgnoreCase)

Ordinal表示Unicode、逐字节、文化无关的比较。

为了正确比较非英语字符,您应该为此使用适当的区域性规则。例如,您可以为瑞典语创建自己的不区分大小写的StringComparer,并在Contains方法中使用它:

var swedishComparer = StringComparer.Create(new CultureInfo("sv-Se"), true);
consultants = consultants
    .Where(x => 
        x.Description.Contains(vm.Description, swedishComparer)
    ).ToList();

这是Joel Spolsky对字符集问题的介绍。非常有趣的阅读。

简而言之,网页需要在页面的一开始就告诉你它正在使用什么字符集。c#使用unicode(以UTF-16编码为标准)作为字符串,这意味着什么你可以在这里找到深度

的解释。

你搜索什么?在xml文件、db40文件、sql ?数据库的字符编码很重要。你可以在xml中设置它的utf编码;db40在对象上已经是安全的,在SQL方面,您必须设置字符编码。

如果您的数据库以char(50)或varchar(50)形式保存值,则可能会丢失不同的字符,因此您应该在sql数据库中使用nchar, nvarchar来保存不同的字符。不要忘记检查您的数据库字符编码,即使它不是很必要

你在做什么样的列表?普通列表还是ORM?使用string.Compare()如果它是一个普通的列表。

索引是搜索的重要组成部分。我认为你最好使用一些现成的、可靠的东西,比如Lucene或Solr。

如果您仍然坚持在非ascii字符上使用正则表达式进行搜索,那么您可能应该更多地了解unicode分类,然后在搜索文本中的单词之前使用它们去除任何重音标记(例如,用'p{P}'p{M}去除重音标记)。

注意:您可能还需要使用FormC标志规范化您的字符串,以便更有效地分解和剥离/搜索

感谢所有提供建议的人,但不幸的是,他们似乎无关紧要。事实证明,Contains()对于非英语字符完全没有问题。问题是数据库字段有html编码的文本,所以我需要使用HtmlDecode来比较控制器中的字符串:

        if (vm.Description != "")
        {
            //HttpUtility.HtmlDecode needed because text in Description field is HtmlEncoded!
            consultants = consultants.Where(x => HttpUtility.HtmlDecode(x.Description).ContainsCaseInsensitive(vm.Description)).ToList();
        }

我发现这是因为Contains()代码在搜索另一个包含非英语字符的字段时工作得很好。