Сравнивать строки с неанглийскими символами? - PullRequest
2 голосов
/ 07 апреля 2011

Мне нужно сравнить строки для механизма поиска на веб-сайте.Я использую C #.Я попробовал два способа:

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

и

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

Оба прекрасно работают для всех английских символов.Так что, если я ищу, скажем, «английский», это не проблема.Но как только я пытаюсь найти строку, содержащую неанглийские символы, она не работает.Например, если я пытаюсь найти слово «språk» («язык» по-шведски), оно ничего не возвращает.

Почему это так и как я могу его решить?

Ответы [ 7 ]

2 голосов
/ 09 апреля 2011

Использование

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

или

c.IndexOf(vm, StringComparison.OrdinalIgnoreCase)

Ordinal означает Unicode, байтовое за байтом, независимое от культуры сравнение.

2 голосов
/ 07 апреля 2011

Для правильного сравнения неанглийских символов вы должны использовать соответствующие правила культуры.Например, вы можете создать свой собственный регистр StringComparer без учета регистра и использовать его в методе Contains:

var swedishComparer = StringComparer.Create(new CultureInfo("sv-Se"), true);

consultants = consultants
    .Where(x => 
        x.Description.Contains(vm.Description, swedishComparer)
    ).ToList();
1 голос
/ 07 апреля 2011

Вот введение в проблему набора символов Джоэля Спольски.Очень интересное чтение.

Короче говоря, веб-страница должна сообщить вам, какой набор символов она использует в самом начале страницы.C # использует Unicode (в кодировке UTF-16 как стандарт) для строк, объяснение, что это значит, вы можете найти здесь в csharp подробно

Надеюсь, это поможет вам.

0 голосов
/ 09 апреля 2011

Спасибо всем, кто предложил предложения, но, к сожалению, они, похоже, не имеют значения.Как оказалось, 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 () работал нормально при поискедругое поле с неанглийскими символами.

0 голосов
/ 07 апреля 2011

Индексирование - большая часть поиска. Я думаю, что вам лучше всего использовать что-то готовое и твердое, например Lucene или Solr .

Если вы по-прежнему настаиваете на поиске с использованием регулярных выражений не-ascii символов, вам, вероятно, следует узнать больше о категориях юникода , а затем использовать их для удаления любых знаков ударения (например, с помощью \p{P} или \p{M}) перед поиском этого слова в тексте.

Примечание: вам также, вероятно, потребуется нормализовать строки, используя флаг FormC , чтобы более эффективно разлагать и разбирать / искать

0 голосов
/ 07 апреля 2011

Над каким списком вы работаете?Простой список или ORM?используйте string.Compare(), если это простой список.

0 голосов
/ 07 апреля 2011

Что вы ищете?На файл XML, на файл db4o, на sql?Кодировка символов вашей базы данных важна.Вы можете справиться с этим в xml, установив его utf-кодирование;и db4o уже безопасно работает на объекте, на стороне sql вы должны установить кодировку charachter.

если ваша база данных содержит значения в виде char (50) или varchar (50), в ней могут отсутствовать разные символы, для хранения разных символов, таких как nchar, nvarchar, следует использовать в своей sql-базе данных.Не забудьте проверить кодировку вашей базы данных, даже если она не так уж необходима

...