Есть ли способ сделать следующий возврат верным?
string title = "ASTRINGTOTEST";
title.Contains("string");
Кажется, не существует перегрузки, которая позволяет мне установить чувствительность к регистру. В настоящее время я ЗАПИСЫВАЮ ВЕРХНИЙ РЕГИСТР их обоих, но это просто глупо (под этим я имею в виду проблемы i18n, которые возникают с верхним и нижним регистром).
ОБНОВИТЬ
Это древний вопрос, и с тех пор я понял, что просил простого ответа на действительно обширную и сложную тему, если вы хотите исследовать ее полностью.
В большинстве случаев в одноязычных, английских кодовых базах ответа это будет достаточно. Я подозреваю, потому что большинство людей, приезжающих сюда, попадают в эту категорию, это самый популярный ответ.
Однако ответ Этот поднимает внутреннюю проблему, заключающуюся в том, что мы не можем сравнивать текст без учета регистра, пока не узнаем, что оба текста принадлежат к одной и той же культуре, и мы не знаем, что это за культура. Возможно, это менее популярный ответ, но я думаю, что он более правильный, и поэтому я отметил его как таковой.





Вы всегда можете сначала просто поднять или опустить струны.
string title = "string":
title.ToUpper().Contains("STRING") // returns true
Ой, только что видел последнюю часть. При сравнении без учета регистра *, возможно, * в любом случае сделает то же самое, и если производительность не является проблемой, я не вижу проблем с созданием копий в верхнем регистре и их сравнением. Я мог бы поклясться, что однажды видел сравнение без учета регистра ...
Ищите "тест индейки" :)
В некоторых французских языках прописные буквы не имеют диакритических знаков, поэтому ToUpper () может быть ничем не лучше ToLower (). Я бы посоветовал использовать подходящие инструменты, если они доступны - сравнение без учета регистра.
Не используйте ToUpper или ToLower и делайте то, что сказал Джон Скит
Только что увидел это снова через два года и новое отрицательное голосование ... в любом случае, я согласен с тем, что есть более эффективные способы сравнения строк. Однако не все программы будут локализованы (большинство - нет), и многие из них являются внутренними или одноразовыми приложениями. Поскольку я не могу рассчитывать на то, что совет лучше всего оставить для одноразовых приложений ... Я двигаюсь дальше: D
Даже если ваше приложение не локализовано, оно все равно может работать в затронутом регионе с действующей культурой локального потока и завершиться ошибкой.
@LonelyPixel: Я полагаю, я хотел сказать, что этот код не должен появляться ни в чем, кроме одноразового приложения. В таком случае, я не думаю, что тебе все равно.
Поиск «теста Турции» - это то же самое, что поиск «теста Турции»?
@JackAce: зависит от приложения.
Вы можете использовать String.IndexOf - метод и передать StringComparison.OrdinalIgnoreCase в качестве используемого типа поиска:
string title = "STRING";
bool contains = title.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0;
Еще лучше определить новый метод расширения для строки:
public static class StringExtensions
{
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
return source?.IndexOf(toCheck, comp) >= 0;
}
}
Обратите внимание, что нулевое распространение?. доступен с C# 6.0 (VS 2015), для более старых версий используйте
if (source == null) return false;
return source.IndexOf(toCheck, comp) >= 0;
ПРИМЕНЕНИЕ:
string title = "STRING";
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase);
Где лучше всего разместить что-то подобное в структуре приложения?
@Andi, у меня обычно есть пара файлов кода с методами расширения общего назначения, куда это могло бы пойти.
@JaredPar: Мне любопытно узнать, есть ли это в .Net 4 или .Net 4.5, знаете ли вы?
@VoodooChild, похоже, это не так. Судя по листингу 4.0 API здесь msdn.microsoft.com/en-us/library/system.string_methods.aspx
Кажется, не работает в запросах Entity Framework (4.x). Вероятно, потому что он находится в части LINQ to SQL. Я получаю следующую ошибку: LINQ to SQL не распознает метод Boolean Contains (System.String, System.String, System.StringComparison), и этот метод не может быть преобразован в выражение хранилища. Подзапрос, выполняемый после возврата результатов, работает. Я не думаю, что это имеет какое-либо отношение к расширению, поскольку LINQ to SQL не знает, как преобразовать код в SQL-запрос.
есть справочный сайт для такого полезного расширения, чтобы поделиться преимуществом. эта запись очень похожа на эту extensionmethod.net/Details.aspx?ID=473
Отличный метод расширения строки! Я отредактировал свой, чтобы проверить, что исходная строка не равна нулю, чтобы предотвратить возникновение ошибок ссылки на объект при выполнении .IndexOf ().
@JookyDFW LINQ to SQL (и LINQ to Entities для базы данных SQL) будет использовать сравнение строк с использованием сортировки по умолчанию в вашей БД, которая в большинстве случаев нечувствительна к регистру, поэтому "СТРОКА" и "строка" совпадают при обращении к БД, но не совпадать по возвращаемым результатам без использования этого расширения.
Это дает тот же ответ, что и paragraph.ToLower(culture).Contains(word.ToLower(culture)) с CultureInfo.InvariantCulture, и не решает никаких проблем с локализацией. Зачем все усложнять? stackoverflow.com/a/15464440/284795
@ColonelPanic версия ToLower включает 2 выделения, которые не нужны при операции сравнения / поиска. Зачем без нужды выделять ресурсы в сценарии, который этого не требует?
А как насчет LINQ IEnumerable.Contains, который позволяет указать параметр StringComparison, например StringComparison.CurrentCultureIgnoreCase? См. MSDN msdn.microsoft.com/en-us/library/bb339118(v=vs.95).aspx
@Seabiscuit, который не будет работать, потому что string - это IEnumerable<char>, поэтому вы не можете использовать его для поиска подстрок
@fiat Раньше это был принятый ответ, но на самом деле это не совсем правильный ответ. Пока вы остаетесь в рамках стандартных латинских символов, это выглядит тривиальной разницей, но для большей части мира это не так. Проблема в том, что я попросил простой ответ на то, что, как я теперь знаю, является действительно сложной темой, и ответ действительно зависит от сценария. Я обновлю исходный вопрос, чтобы отразить это.
В качестве предпочтения стиля я бы просто добавил явный метод, а не перегрузку Contains: public static bool ContainsIgnoreCase (этот источник строки, строка toCheck) {return source.IndexOf (toCheck, StringComparison.OrdinalIgnoreCase)> = 0; }
@CodeBlend, скорее всего, они протестировали весь свой внутренний материал, который знает об их изменениях, и никто не проверял (или никого не заботил), что он сломал все внешние ссылки.
Предупреждение: по умолчанию для string.IndexOf(string) используется текущая культура, а для string.Contains(string) по умолчанию используется порядковый компаратор. Как мы знаем, первое можно изменить, выбрав более длительную перегрузку, а второе изменить нельзя. Следствием этого несоответствия является следующий образец кода: Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; string self = "Waldstrasse"; string value = "straße"; Console.WriteLine(self.Contains(value));/* False */ Console.WriteLine(self.IndexOf(value) >= 0);/* True */
Нельзя расширить для нестатических универсальных классов ... разве это не проблема, по крайней мере, в 50% случаев для всех?
Как источник может быть нулевым? Это метод расширения.
Метод расширения @KyleDelaney this может иметь значение null. Хотелось бы, чтобы в C# была встроенная проверка на null, но ее нет.
Я применил тот же метод расширения, однако вместо этого я проверил null в строке toCheck, если кодировщик передает нулевое значение, метод IndexOf все равно генерирует исключение ArgumentNullException. Таким образом, метод расширения может проверять как источник, так и toCheck на отказоустойчивость.
@Iain Если вы вызываете myString.SomeMethod(), а myString имеет значение null, вы действительно заслуживаете исключения для нулевого указателя. Проверять это - не задача метода расширения.
@Nyerguds нет, вызывая метод расширения по нулевому указателю работает. Меня это удивило, когда я впервые это увидел, но: shrug:
@Iain Моя точка зрения остается неизменной; даже если это работает, это не задача метода, чтобы проверить это, потому что расширения должны действовать как обычные функции, выполняемые над объектом. Тем не менее, это, безусловно, полезно знать об этой маленькой причуде.
Вы можете использовать IndexOf() так:
string title = "STRING";
if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
// The string exists in the original
}
Поскольку 0 (ноль) может быть индексом, вы проверяете значение -1.
The zero-based index position of value if that string is found, or -1 if it is not. If value is String.Empty, the return value is 0.
Альтернативное решение с использованием Regex:
bool contains = Regex.IsMatch("StRiNG to search", Regex.Escape("string"), RegexOptions.IgnoreCase);
Хорошая идея, также у нас есть много побитовых комбинаций в RegexOptions, таких как RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant;, для всех, если это поможет.
Должен сказать, что предпочитаю этот метод, хотя для наглядности использую IsMatch.
Что еще хуже, поскольку строка поиска интерпретируется как регулярное выражение, ряд знаков пунктуации приведет к неверным результатам (или вызовет исключение из-за недопустимого выражения). Попробуйте поискать "." в "This is a sample string that doesn't contain the search string". Или попробуйте поискать "(invalid", если на то пошло.
@cHao: В этом случае может помочь Regex.Escape. Регулярное выражение все еще кажется ненужным, когда IndexOf / extension Contains прост (и, возможно, более понятен).
Обратите внимание, что я не имел в виду, что это решение Regex было лучшим вариантом. Я просто добавлял в список ответов на исходный заданный вопрос «Есть ли способ сделать следующий возврат верным?».
@cHao: спасибо, что выделили это, осветили. Тем не менее, я предпочитаю этот способ из-за неотъемлемой силы регулярных выражений.
Это будет значительно менее эффективно, чем использование IndexOf. Использование Regex значительно увеличит время обработки, память и т. д.
Поскольку это не работает в простых сценариях («.», «Здесь нет точки»), это нет - «альтернативное решение».
@Saravanan, вы перепутали И & с ИЛИ |, вместо этого должен быть RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant;.
Класс StringExtension - это путь вперед, я объединил пару сообщений выше, чтобы дать полный пример кода:
public static class StringExtensions
{
/// <summary>
/// Allows case insensitive checks
/// </summary>
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
return source.IndexOf(toCheck, comp) >= 0;
}
}
почему вы разрешаете ДРУГОЙ уровень абстракции поверх StringComparison?
Потому что это упрощает как чтение, так и написание кода. По сути, он имитирует то, что более поздние версии .Net добавили непосредственно в класс. Можно многое сказать о простых удобных методах, которые облегчают вашу жизнь и жизнь других, даже если они добавляют немного абстракции.
Одна из проблем с ответом заключается в том, что он вызовет исключение, если строка имеет значение NULL. Вы можете добавить это как проверку, чтобы этого не произошло:
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
return true;
return source.IndexOf(toCheck, comp) >= 0;
}
Если toCheck - пустая строка, она должна вернуть true согласно документации Contains: «true, если параметр value встречается в этой строке, или если value является пустой строкой (" "); в противном случае - false."
Основываясь на приведенном выше комментарии Амурры, не нужно ли исправлять предлагаемый код? И не следует ли это добавить к принятому ответу, чтобы сначала был лучший ответ?
Теперь это вернет истину, если источник - пустая строка или ноль, независимо от того, что такое toCheck. Это не может быть правильным. Также IndexOf уже возвращает истину, если toCheck - пустая строка, а источник не равен нулю. Здесь нужна проверка на нуль. Я предлагаю if (source == null || value == null) return false;
Источник не может быть нулевым
if (string.IsNullOrEmpty(source)) return string.IsNullOrEmpty(toCheck);Итак, пустая строка содержит «Foo» ... как это правда?
Мне пришлось проголосовать против этого, а также еще 6 человек, это просто неправильно. должен быть return false;, а не return true;
Использовать это:
string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);
Спрашивающий ищет Contains, а не Compare.
@DuckMaestro, принятый ответ реализует Contains с IndexOf. Так что этот подход одинаково полезен! В примере кода C# на эта страница используется string.Compare (). Выбор команды SharePoint!
Знаю, что это не C#, но в фреймворке (VB.NET) уже есть такая функция
Dim str As String = "UPPERlower"
Dim b As Boolean = InStr(str, "UpperLower")
Вариант C#:
string myString = "Hello World";
bool contains = Microsoft.VisualBasic.Strings.InStr(myString, "world");
Это чисто и просто.
Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)
Однако это будет соответствовать шаблону. В вашем примере, если в fileNamestr есть какие-либо специальные символы регулярного выражения (например, *, +, . и т. д.), Вы будете приятно удивлены. Единственный способ заставить это решение работать как правильная функция Contains - это выйти из fileNamestr, выполнив Regex.Escape(fileNamestr).
кроме того, синтаксический анализ и сопоставление регулярного выражения намного более ресурсозатратны, чем простое сравнение без учета регистра
Чтобы проверить, содержит ли строка paragraph строку word (спасибо @QuarterMeister)
culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0
Где culture - это экземпляр CultureInfo, описывающий язык, на котором написан текст.
Это решение прозрачно для определение нечувствительности к регистру, которое зависит от языка. Например, английский язык использует символы I и i для прописных и строчных версий девятой буквы, тогда как турецкий язык использует эти символы для одиннадцатая и двенадцатая буквы своего 29-буквенного алфавита. Версия «i» в турецком верхнем регистре - это незнакомый символ «İ».
Таким образом, строки tin и TIN - это одно и то же слово на английском, но разные слова в Турции. Насколько я понимаю, одно означает «дух», а другое - звукоподражательное слово. (Турки, поправьте меня, пожалуйста, если я ошибаюсь, или подскажите пример получше)
Подводя итог, вы можете ответить только на вопрос «являются ли эти две строки одинаковыми, но в разных случаях» если вы знаете, на каком языке написан текст. Если вы не знаете, вам придется покататься на лодке. Учитывая гегемонию английского языка в программном обеспечении, вам, вероятно, следует прибегнуть к CultureInfo.InvariantCulture, потому что он будет неправильным в привычных отношениях.
Я понимаю вашу точку зрения, и вы, вероятно, правы. Это старый вопрос, и мне нужно перечитать его еще раз, но я думаю, что изменю принятый ответ.
Почему не culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0? При этом используется правильный язык и региональные параметры, не учитывается регистр, не выделяются временные строчные строки, и не возникает вопроса о том, всегда ли преобразование в нижний регистр и сравнение аналогичны сравнению без учета регистра.
@Quartermeister, это сработает. Я попытался выяснить, как CompareInfo.IndexOf определяет сравнение без учета регистра, но этот метод просто обертывает недокументированный InternalFindNLSStringEx.
Это решение также бесполезно загрязняет кучу, выделяя память для того, что должно быть функцией поиска.
Сравнение с ToLower () даст разные результаты из-за нечувствительности к регистру IndexOf, когда две разные буквы имеют одну и ту же строчную букву. Например, вызов ToLower () для U + 0398 «греческая заглавная буква тета» или U + 03F4 «греческий заглавная буква тета» приводит к U + 03B8, «греческая строчная буква тета», но заглавные буквы считаются разными. В обоих решениях строчные буквы с одной и той же заглавной буквой различаются, например, U + 0073 «Латинская строчная буква S» и U + 017F «Латинская строчная длинная буква S», поэтому решение IndexOf кажется более последовательным.
Для FindNLSStringEx есть документация MSDN, которая, вероятно, применима к InternalFindNLSStringEx. Флаг - NORM_IGNORECASE, который «игнорирует любое третичное различие, независимо от того, действительно ли это лингвистический случай», но я недостаточно знаю о NLS, чтобы понять, что такое «третичное различие».
Чтобы сделать этот ответ немного более полным, учитывая, что вы хотите заниматься веб-майнингом: если вы не знаете язык страницы априори, вы можете довольно легко выяснить это с помощью простой языковой модели, основанной на униграммах. Единственная проблема - получить данные для достаточного количества разных языков - но, вероятно, существуют библиотеки, которые могут предсказать язык страницы - я думаю, это достаточно распространенная проблема.
@Quartermeister - третичное различие - это регистр. Может быть лингвистическим (турецкий i -> İ) или нет (ascii i -> I). Определение можно найти на сайте oracle: docs.oracle.com/cd/B28359_01/server.111/b28298/…, подробнее о лингвистическом корпусе здесь: blogs.msdn.com/b/michkap/archive/2004/12/11/279942.aspx
@Quartermeister - и, кстати, я считаю, что .NET 2 и .NET4 ведут себя по-разному, поскольку .NET 4 всегда использует NORM_LINGUISTIC_CASING, а .NET 2 - нет (эти флаги появились в Windows Vista).
Следует ли переместить метод с CompareOptions.IgnoreCase первым, потому что .ToLower явно неэффективен?
В том же духе я бы рекомендовал добавить CompareOptions.IgnoreKanaType и CompareOptions.IgnoreWidth.
Почему вы не написали «ddddfg» .IndexOf («Df», StringComparison.OrdinalIgnoreCase)?
Я только что пробовал это. Я ищу 154 строковых шаблона в 40 000 файлов, игнорируя нижний регистр. Он очень медленный и работал часами. Использование Regex или ToLower может быть более подвержено ошибкам при поиске не на английском языке, но они оба намного быстрее.
должно быть> -1 нет? Возможно, найденный индекс будет иметь индекс 0, и это не удастся. IndexOf возвращает -1, если не найден в строке.
Совет: вместо использования текущего языка и региональных параметров для значения cultureInfo можно также использовать CultureInfo.InvariantCulture.
SIK и sik. Большая разница.
строка title = "строка"; строка tobeCompared = "СТРОКА"; if (title.ToUpper (). Contains (tobeCompared.ToUpper ())) {// Напишите здесь свою логику} else {// Напишите здесь свою логику}
Использование RegEx - простой способ сделать это:
Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
Ваш ответ точно такой же, как у guptat59, но, как было указано в его ответе, это будет соответствовать регулярному выражению, поэтому, если строка, которую вы тестируете, содержит какие-либо специальные символы регулярного выражения, она не даст желаемого результата.
Это прямая копия этот ответ и страдает теми же проблемами, что отмечены в этом ответе
Согласовано. Изучите регулярные выражения
Метод InStr из сборки VisualBasic лучше всего подходит, если вас беспокоит интернационализация (или вы могли бы реализовать его заново). Глядя на него, dotNeetPeek показывает, что он учитывает не только заглавные и строчные буквы, но и тип кана, а также символы полной и половинной ширины (в основном актуально для азиатских языков, хотя есть и полноширинные версии латинского алфавита. ). Я пропускаю некоторые детали, но обратите внимание на частный метод InternalInStrText:
private static int InternalInStrText(int lStartPos, string sSrc, string sFind)
{
int num = sSrc == null ? 0 : sSrc.Length;
if (lStartPos > num || num == 0)
return -1;
if (sFind == null || sFind.Length == 0)
return lStartPos;
else
return Utils.GetCultureInfo().CompareInfo.IndexOf(sSrc, sFind, lStartPos, CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth);
}
OrdinalIgnoreCase, CurrentCultureIgnoreCase или InvariantCultureIgnoreCase?
Поскольку этого нет, вот несколько рекомендаций о том, когда какой из них использовать:
StringComparison.OrdinalIgnoreCase для сравнения
в качестве безопасного значения по умолчанию для сопоставления строк, не зависящего от языка и региональных параметров.StringComparison.OrdinalIgnoreCase
для увеличения скорости.StringComparison.CurrentCulture-based
при отображении вывода пользователю.StringComparison.Ordinal или StringComparison.OrdinalIgnoreCase при сравнении ToUpperInvariant, а не ToLowerInvariant, когда
нормализующие строки для сравнения.StringComparison.InvariantCultureИсходя из этих правил, вы должны использовать:
string title = "STRING";
if (title.IndexOf("string", 0, StringComparison.[YourDecision]) != -1)
{
// The string exists in the original
}
тогда как [YourDecision] зависит от рекомендаций сверху.
ссылка на источник: http://msdn.microsoft.com/en-us/library/ms973919.aspx
что, если вы знаете, что всегда получите английскую строку. какой использовать?
@BKSpurgeon Я бы использовал OrdinalIgnoreCase, если случай не имеет значения
Именно так:
string s = "AbcdEf";
if (s.ToLower().Contains("def"))
{
Console.WriteLine("yes");
}
Это не зависит от культуры и в некоторых случаях может не работать. Необходимо использовать культуру.CompareInfo.IndexOf (абзац, слово, CompareOptions.IgnoreCase).
Это очень похоже на другой пример здесь, но я решил упростить enum до bool, primary, потому что другие альтернативы обычно не нужны. Вот мой пример:
public static class StringExtensions
{
public static bool Contains(this string source, string toCheck, bool bCaseInsensitive )
{
return source.IndexOf(toCheck, bCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) >= 0;
}
}
А использование выглядит примерно так:
if ( "main String substring".Contains("SUBSTRING", true) )
....
Уловка здесь заключается в том, чтобы искать строку, игнорируя регистр, но оставляя ее точно такой же (с тем же регистром).
var s = "Factory Reset";
var txt = "reset";
int first = s.IndexOf(txt, StringComparison.InvariantCultureIgnoreCase) + txt.Length;
var subString = s.Substring(first - txt.Length, txt.Length);
Выход "Сброс"
if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}
Вы можете использовать функцию string.indexof (). Это будет нечувствительно к регистру
Простой способ для новичка:
title.ToLower().Contains("string");//of course "string" is lowercase.
Проголосовать против просто за неправильность. Что если title = StRiNg? StRiNg! = Строка и StRiNg! = STRING
Я ошибался. Отредактируйте ответ следующим образом, слишком просто: <br/> title.ToLower (). Contains ("string") // конечно, "string" в нижнем регистре
public static class StringExtension
{
#region Public Methods
public static bool ExContains(this string fullText, string value)
{
return ExIndexOf(fullText, value) > -1;
}
public static bool ExEquals(this string text, string textToCompare)
{
return text.Equals(textToCompare, StringComparison.OrdinalIgnoreCase);
}
public static bool ExHasAllEquals(this string text, params string[] textArgs)
{
for (int index = 0; index < textArgs.Length; index++)
if (ExEquals(text, textArgs[index]) == false) return false;
return true;
}
public static bool ExHasEquals(this string text, params string[] textArgs)
{
for (int index = 0; index < textArgs.Length; index++)
if (ExEquals(text, textArgs[index])) return true;
return false;
}
public static bool ExHasNoEquals(this string text, params string[] textArgs)
{
return ExHasEquals(text, textArgs) == false;
}
public static bool ExHasNotAllEquals(this string text, params string[] textArgs)
{
for (int index = 0; index < textArgs.Length; index++)
if (ExEquals(text, textArgs[index])) return false;
return true;
}
/// <summary>
/// Reports the zero-based index of the first occurrence of the specified string
/// in the current System.String object using StringComparison.InvariantCultureIgnoreCase.
/// A parameter specifies the type of search to use for the specified string.
/// </summary>
/// <param name = "fullText">
/// The string to search inside.
/// </param>
/// <param name = "value">
/// The string to seek.
/// </param>
/// <returns>
/// The index position of the value parameter if that string is found, or -1 if it
/// is not. If value is System.String.Empty, the return value is 0.
/// </returns>
/// <exception cref = "ArgumentNullException">
/// fullText or value is null.
/// </exception>
public static int ExIndexOf(this string fullText, string value)
{
return fullText.IndexOf(value, StringComparison.OrdinalIgnoreCase);
}
public static bool ExNotEquals(this string text, string textToCompare)
{
return ExEquals(text, textToCompare) == false;
}
#endregion Public Methods
}
если вы хотите проверить, находится ли ваша переданная строка в строке, для этого есть простой метод.
string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";
bool isContained = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;
Это логическое значение вернется, если строка содержится или нет
Это самые простые решения.
По индексу
string title = "STRING";
if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
// contains
}
Изменяя регистр
string title = "STRING";
bool contains = title.ToLower().Contains("string")
По Regex
Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
В .NET Core начиная с версии 2.0 есть пара методов, позволяющих справиться с этим:
Пример:
"Test".Contains("test", System.StringComparison.CurrentCultureIgnoreCase);
Со временем они, вероятно, войдут в стандарт .NET, а оттуда во все другие реализации библиотеки базовых классов.
Теперь также доступно в .NET Standard 2.1
Также доступно в .NET 5.0.
Чтобы развить ответ здесь, вы можете создать метод расширения строки, чтобы сделать его немного более удобным для пользователя:
public static bool ContainsIgnoreCase(this string paragraph, string word)
{
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
}
Предполагая, что ваш абзац и слово всегда будут на английском языке
Чтобы избежать проблем с принудительным переводом языка и региональных параметров в en-US, используйте вместо этого return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;.
Как просто так и работает
title.ToLower().Contains("String".ToLower())
Аналогично предыдущим ответам (с использованием метода расширения), но с двумя простыми нулевыми проверками (C# 6.0 и выше):
public static bool ContainsIgnoreCase(this string source, string substring)
{
return source?.IndexOf(substring ?? "", StringComparison.OrdinalIgnoreCase) >= 0;
}
Если источник равен нулю, вернуть ложь (через оператор распространения нуля?.)
Если подстрока равна нулю, рассматривать ее как пустую строку и возвращать истину (с помощью оператора объединения с нулем ??)
StringComparison, конечно, может быть отправлен в качестве параметра при необходимости.
Основываясь на существующих ответах и документации метода Contains, я бы рекомендовал создать следующее расширение, которое также позаботится о угловых случаях:
public static class VStringExtensions
{
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
if (toCheck == null)
{
throw new ArgumentNullException(nameof(toCheck));
}
if (source.Equals(string.Empty))
{
return false;
}
if (toCheck.Equals(string.Empty))
{
return true;
}
return source.IndexOf(toCheck, comp) >= 0;
}
}
Вы можете использовать параметр сравнения строк (доступен в .net 2.1 и выше) String.Contains - метод.
public bool Contains (string value, StringComparison comparisonType);
Пример:
string title = "ASTRINGTOTEST";
title.Contains("string", StringComparison.InvariantCultureIgnoreCase);
да, он доступен в .net Standard 2.1 и .Net Core 5.0 docs.microsoft.com/en-us/dotnet/api/… Исправлено как часть - github.com/dotnet/runtime/issues/22198
Интересно, что я видел, как ToUpper () рекомендуется использовать вместо ToLower () в подобном сценарии, потому что, очевидно, ToLower () может «потерять точность» в определенных культурах, то есть два разных символа верхнего регистра переводятся в одно и то же строчный символ.