不区分大小写'包含(string)'

有没有办法让以下回报为真?

string title = "ASTRINGTOTEST"; title.Contains("string"); 

似乎没有一个超载,允许我设置区分大小写。目前,我大写它们两个,但这只是愚蠢的。

UPDATE
我提到的这个愚蠢的问题是上下套pipe问题。

UPDATE
这个问题是古老的,从那时起,我意识到我要求一个简单的答案,如果你真的关心一个非常广泛而困难的话题,那么就全面地调查它。
对于大多数情况下,在单语言,英文的代码基础上, 这个答案就足够了。 我怀疑是因为大多数来这里的人都属于这个类别,这是最受欢迎的答案。
然而, 这个答案带来了固有的问题,我们不能比较文本不区分大小写,直到我们知道两个文本是相同的文化,我们知道那个文化是什么。 这可能是一个不太stream行的答案,但我认为这是更正确的,这就是为什么我这样标记。

要testingstringparagraph包含stringword (谢谢@QuarterMeister)

 culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0 

cultureCultureInfo描述文本所写语言的实例。

这个解决scheme对于不区分大小写的定义是透明的,这与语言相关 。 例如,英文使用第九个字母的大写和小写字母Ii ,而土耳其语使用这些字符作为第二十九个字母的第十一个和第十二个字母。 土耳其的大写版本的'我'是陌生的字符'İ'。

因此tinTIN的string在英语中是相同的单词,但在土耳其语中是不同的单词。 据我所知,一个意思是“灵”,另一个是象声词。 (土耳其人,请纠正我,如果我错了,或build议一个更好的例子)

总而言之, 如果你知道文字是什么语言 ,你只能回答这个问题“这两个string是否相同,但是在不同的情况下” 如果你不知道,你将不得不平息。 鉴于英语在软件方面的霸权,你应该诉诸CultureInfo.InvariantCulture ,因为它会以熟悉的方式出错。

您可以使用String.IndexOf方法并传递StringComparison.OrdinalIgnoreCase作为要使用的searchtypes:

 string title = "STRING"; bool contains = title.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0; 

更好的是为string定义一个新的扩展方法:

 public static class StringExtensions { public static bool Contains(this string source, string toCheck, StringComparison comp) { return source.IndexOf(toCheck, comp) >= 0; } } ... string title = "STRING"; bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase); 

你可以像这样使用IndexOf()

 string title = "STRING"; if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1) { // The string exists in the original } 

由于0(零)可以是一个索引,你检查-1。

MSDN

如果find该string,则返回从零开始的索引位置;如果不是,则为-1。 如果value是String.Empty,则返回值是0。

使用正则expression式的替代解决scheme:

 bool contains = Regex.IsMatch("StRiNG to search", "string", RegexOptions.IgnoreCase); 

注意

正如@cHao在他的评论中指出的,有一些情况会导致这个解决scheme返回不正确的结果。 在你实施这个解决scheme之前,确保你知道你在做什么。

你总是可以首先上弦或下弦。

 string title = "string": title.ToUpper().Contains("STRING") // returns true 

哎呀,只是看到了最后一点。 不区分大小写的比较可能会做同样的事情,如果性能不是问题,我不会看到创build大写副本和比较这些问题。 我可以发誓,我曾经看到一个不区分大小写的比较一次…

答案的一个问题是,如果一个string为空,它将引发exception。 你可以添加,作为一个支票,所以它不会:

 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; } 

StringExtension类是前进的方向,我已经结合了上面的几个post来给出一个完整的代码示例:

 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; } } 

这是干净和简单的。

 Regex.IsMatch(file,fileNamestr,RegexOptions.IgnoreCase) 

OrdinalIgnoreCase,CurrentCultureIgnoreCase或InvariantCultureIgnoreCase?

由于缺失,下面是关于何时使用哪一个的build议:

DOS

  • 使用StringComparison.OrdinalIgnoreCase进行比较,作为文化无关string匹配的安全默认值。
  • 使用StringComparison.OrdinalIgnoreCase比较来提高速度。
  • 将输出显示给用户时,使用StringComparison.CurrentCulture-basedstring操作。
  • 切换当前使用的基于不变文化的string操作,在比较时使用非语言的StringComparison.OrdinalStringComparison.OrdinalIgnoreCase
    语言无关(例如象征性的)。
  • 标准化string进行比较时,使用ToUpperInvariant而不是ToLowerInvariant

注意事项

  • 对于没有显式或隐式指定string比较机制的string操作使用重载。
  • 使用StringComparison.InvariantCulture的string
    大多数情况下的操作; less数例外之一是
    坚持语言上有意义但文化上不可知论的数据。

基于这些规则你应该使用:

 string title = "STRING"; if (title.IndexOf("string", 0, StringComparison.[YourDecision]) != -1) { // The string exists in the original } 

而[YourDecision]取决于上面的build议。

链接的来源: http : //msdn.microsoft.com/en-us/library/ms973919.aspx

像这样:

 string s="AbcdEf"; if(s.ToLower().Contains("def")) { Console.WriteLine("yes"); } 

我知道这不是C#,但在框架(VB.NET)中已经有了这样的function

 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"); 

从VisualBasic程序集的InStr方法是最好的,如果你有关于国际化的问题(或者你可以重新实现)。 着眼于它,dotNeetPeek表明,它不仅涵盖了大小写,还包括假名types和全angular与半angular字符(大部分与亚洲语言相关,尽pipe也有罗马字母的全angular版本)。 我正在跳过一些细节,但查看私有方法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); } 

用这个:

 string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase); 

最终,通用的“包含”操作归结为这样的function,

 /// <summary> /// Determines whether the source contains the sequence. /// </summary> /// <typeparam name="T">The type of the items in the sequences.</typeparam> /// <param name="sourceEnumerator">The source enumerator.</param> /// <param name="sequenceEnumerator">The sequence enumerator.</param> /// <param name="equalityComparer">An equality comparer.</param> /// <remarks> /// An empty sequence will return <c>true</c>. /// The sequence must support <see cref="IEnumerator.Reset"/> /// if it does not begin the source. /// </remarks> /// <returns> /// <c>true</c> if the source contains the sequence; /// otherwise <c>false</c>. /// </returns> public static bool Contains<T>( IEnumerator<T> sourceEnumerator, IEnumerator<T> sequenceEnumerator, IEqualityComparer<T> equalityComparer) { if (equalityComparer == null) { equalityComparer = EqualityComparer<T>.Default; } while (sequenceEnumerator.MoveNext()) { if (sourceEnumerator.MoveNext()) { if (!equalityComparer.Equals( sourceEnumerator.Current, sequenceEnumerator.Current)) { sequenceEnumerator.Reset(); } } else { return false; } } return true; } 

这可以在接受IEnumerable的扩展版本中这样简单地包装,

 public static bool Contains<T>( this IEnumerable<T> source, IEnumerable<T> sequence, IEqualityComparer<T> equalityComparer = null) { if (sequence == null) { throw new ArgumentNullException("sequence"); } using(var sequenceEnumerator = sequence.GetEnumerator()) using(var sourceEnumerator = source.GetEnumerator()) { return Contains( sourceEnumerator, sequenceEnumerator, equalityComparer); } } 

现在,这将适用于任何序列(包括string)的序数比较,因为string实现IEnumerable<char>

 // The optional parameter ensures the generic overload is invoked // not the string.Contains() implementation. "testable".Contains("est", EqualityComparer<char>.Default) 

但是,正如我们所知,string不是通用的,它们是专用的。 有两个关键因素在起作用。

  1. 本身具有各种语言依赖边缘情况的“套pipe”问题。
  2. Unicode代码点如何表示一组“文本元素”(字母/数字/符号等),以及哪些有效的字符序列可以表示给定的string, 这些 问题相当复杂 。

净效应是一样的。 您可能声明的string在语言上相同,可以由不同的字符组合来有效地表示。 更重要的是,文化之间有效性的变化规则。

所有这些都导致了像这样的基于“Contains”的专门的string。

 using System.Globalization; public static bool Contains( this string source, string value, CultureInfo culture = null, CompareOptions options = CompareOptions.None) { if (value == null) { throw new ArgumentNullException("value"); } var compareInfo = culture == null ? CultureInfo.CurrentCulture.CompareInfo : culture.CompareInfo; var sourceEnumerator = StringInfo.GetTextElementEnumerator(source); var sequenceEnumerator = StringInfo.GetTextElementEnumerator(value); while (sequenceEnumerator.MoveNext()) { if (sourceEnumerator.MoveNext()) { if (!(compareInfo.Compare( sourceEnumerator.Current, sequenceEnumerator.Current, options) == 0)) { sequenceEnumerator.Reset(); } } else { return false; } } return true; } 

这个函数可以用来执行一个不区分大小写的文化特定的“包含”,无论标准化的string是什么,都可以工作。 例如

 "testable".Contains("EST", StringComparer.CurrentCultureIgnoreCase) 

这里和其他例子非常相似,但是我决定把枚举简化为bool,因为通常不需要其他替代方法。 这是我的例子:

 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) ) .... 

使用RegEx是一个直接的方法来做到这一点:

 Regex.IsMatch(title, "string", RegexOptions.IgnoreCase); 
 if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;} 

你可以使用string.indexof ()函数。 这将不区分大小写

这里的诀窍是查找string,忽略大小写,但保持完全相同(使用相同的大小写)。

  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); 

输出是“重置”

 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 } 

简单的方法为新手:

 title.Contains("string") || title.Contains("string".ToUpper());