24 题: 不区分大小写'包含(字符串)'

在...创建的问题 Wed, Jun 6, 2018 12:00 AM

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

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

似乎没有一个重载允许我设置区分大小写。目前我大写它们两个,但那只是愚蠢(我指的是 i18n 上下套管附带的问题。)

更新强>结果 这个问题很古老,从那时起我就意识到,如果你想彻底调查它,我会要求一个简单的答案来解决一个非常庞大而困难的话题。
对于大多数情况,使用单语言,英语代码基础这个答案就足够了。我怀疑是因为大多数人来到这个类别这是最受欢迎的答案。
这个答案然而提出了我们无法比较文本不区分大小写的固有问题,直到我们知道两种文本是相同的文化并且我们知道文化是什么。这可能是一个不那么受欢迎的答案,但我认为它更正确,这就是我将其标记为原因的原因。

    
2686
24答案                              24 跨度>                         

测试字符串paragraph是否包含字符串word(感谢@QuarterMeister)

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

其中culture CultureInfo 描述了写入文本的语言。

此解决方案对于不区分大小写的定义是透明的,这是与语言相关的。例如,英语使用字符Ii作为第九个字母的大写和小写版本,而土耳其语使用这些字符作为第11和第12个字母。土耳其大写版本的'i'是不熟悉的角色'İ'。

因此,字符串tinTIN与英语中的单词相同,但土耳其语中的单词不同。据我所知,一个是“精神”,另一个是拟声词。 (土耳其人,如果我错了,请纠正我,或建议一个更好的例子)

总而言之,如果您知道文本在中的语言,那么您只能回答'这两个字符串是否相同但在不同情况下'的问题。如果你不知道,你将不得不采取行动。鉴于英语在软件方面的霸权,你应该诉诸于 CultureInfo.InvariantCulture ,因为它将是以熟悉的方式做错了。

    
1258
2017-08-10 12:06:38Z
  1. 为什么不是culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0?它使用正确的文化并且不区分大小写,它不分配临时小写字符串,并且它避免了转换为小写和比较是否总是与不区分大小写的比较相同的问题。
    2013-03-18 15:32:39Z
  2. 此解决方案还通过为应该是搜索函数分配内存来不必要地污染堆
    2013-03-18 16:09:38Z
  3. 当两个不同的字母具有相同的小写字母时,与ToLower()相比,将从不区分大小写的IndexOf中给出不同的结果。例如,在U + 0398“希腊大写字母Theta”或U + 03F4“希腊大写字母Theta符号”上调用ToLower()会产生U + 03B8,“希腊小写字母Theta”,但大写字母被认为是不同的。两种解决方案都考虑使用相同大写字母的小写字母,例如U + 0073“Latin Small Letter S”和U + 017F“Latin Small Letter Long S”,因此IndexOf解决方案似乎更加一致。
    2013-03-18 17:47:27Z
  4. + 1表示完整性 - 具有适当解释形式的答案是用户实际从SO中学习的唯一方式
2014-05-05 12:57:04Z
  • 为什么不写“ddddfg”.IndexOf(“Df”,StringComparison.OrdinalIgnoreCase)?
    2015-08-23 13:41:49Z
  • 醇>

    您可以使用 String.IndexOf Method 并通过 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);
    
        
    2549
    2018-05-08 12:57:07Z
    1. 很棒的字符串扩展方法!我编辑了我的,检查源字符串是否为空,以防止在执行.IndexOf()时发生任何对象引用错误。
      2013-02-08 10:48:45Z
    2. 这给出了与paragraph.ToLower(culture).Contains(word.ToLower(culture)) CultureInfo.InvariantCulture相同的答案,并没有解决任何本地化问题。为什么复杂的事情? stackoverflow.com/a/15464440/284795
      2013-03-17 18:52:43Z
    3. @ ColonelPanic ToLower版本包含2个分配,这些分配在比较/搜索操作中是不必要的。为什么在不需要它的场景中进行不必要的分配?
      2013-03-18 16:09:08Z
    4. @ Seabiscuit无效,因为stringIEnumerable<char>因此你不能用它来查找子串
      2014-11-06 17:55:52Z
    5. 警告: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 */
      2016-02-18 09:40:37Z
    6. 醇>

    您可以像这样使用IndexOf()

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

    由于0(零)可以是索引,因此请检查-1。

    MSDN

      

    如果找到该字符串,则从零开始的索引位置值为-1   如果不是。如果value为String.Empty,则返回值为0.

        
    216
    2015-09-15 15:45:31Z

    使用正则表达式的替代解决方案:

     
    bool contains = Regex.IsMatch("StRiNG to search", Regex.Escape("string"), RegexOptions.IgnoreCase);
    
        
    130
    2018-12-17 09:18:03Z
    1. 好主意,我们在RegexOptions中有很多按位组合,例如RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant;,如果有帮助的话。
      2011-08-24 04:36:30Z
    2. 必须说我更喜欢这个尽管使用IsMatch来保持整洁。
      2011-09-07 17:40:01Z
    3. 更糟糕的是,由于搜索字符串被解释为正则表达式,因此许多标点字符将导致错误的结果(或由于表达式无效而触发异常)。尝试在"."中搜索"This is a sample string that doesn't contain the search string"。或者尝试搜索"(invalid",就此而言。
      2011-09-09 13:28:56Z
    4. @ cHao:在这种情况下,Regex.Escape可以提供帮助。当IndexOf /extension Contains很简单(并且可以说更清楚)时,正则表达式似乎仍然没必要。
      2011-09-09 16:44:22Z
    5. 请注意,我并不是说这个Regex解决方案是最好的方法。我只是添加到原始发布问题的答案列表中“是否有办法使以下返回true?”。
      2011-09-13 15:43:25Z
    6. 醇>

    您可以随时向上或向下对齐字符串。

     
    string title = "string":
    title.ToUpper().Contains("STRING")  // returns true
    
    哎呀,刚看到最后一点。不区分大小写的比较*可能*无论如何也是如此,如果性能不是问题,我认为创建大写副本并比较它们没有问题。我曾经发誓我曾经看过一次不区分大小写的比较......     
    73
    2009-01-14 21:54:21Z
    1. 有趣的是,我已经看到ToUpper()在这种情况下推荐使用ToLower(),因为显然ToLower()在某些情况下会“失去保真度”文化 - 也就是说,两个不同的大写字符转换为相同的小写字符。
      2009-01-14 21:47:09Z
    2. 搜索“土耳其测试”:)
      2009-01-14 21:48:30Z
    3. 在某些法语区域设置中,大写字母没有变音符号,因此ToUpper()可能不会比ToLower()更好。如果它们可用,我会说使用适当的工具 - 不区分大小写比较。
      2009-01-14 22:03:59Z
    4. 不要使用ToUpper或ToLower,并做Jon Skeet所说的
      2009-08-21 02:49:03Z
    5. 两年后再次看到这个和一个新的downvote ...无论如何,我同意有更好的方法来比较字符串。但是,并非所有程序都将本地化(大多数不会),许多程序是内部或一次性应用程序。因为我几乎不能期望获得最佳留给一次性应用程序的建议...我正在继续:D
      2011-01-25 07:28:26Z
    6. 醇>

    答案的一个问题是,如果字符串为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;
    } 
    
        
    50
    2015-06-05 06:02:45Z
    1. 如果toCheck是空字符串,则需要根据Contains文档返回true:“如果value参数出现在此字符串中,或​​者如果value为空字符串,则为true( “”);否则,假。“
      2011-02-16 16:13:42Z
    2. 根据上述amurra的评论,建议的代码是否需要更正?并且不应该将其添加到已接受的答案中,以便最好的响应是第一个?
      2011-08-30 03:43:38Z
    3. 现在如果source是空字符串,则返回true,无论toCheck是什么,这都将返回null。这不可能是正确的。如果toCheck为空字符串且source不为null,则IndexOf也会返回true。这里需要检查null。我建议if(source == null || value == null)返回false;
      2013-07-01 12:21:20Z
    4. 源无法为null
      2016-12-14 16:55:26Z
    5. if (string.IsNullOrEmpty(source)) return string.IsNullOrEmpty(toCheck);
      2018-04-04 13:39:04Z
    6. 醇>

    这很干净简单。

     
    Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)
    
        
    35
    2018-06-06 14:54:20Z
    1. 但这将与模式匹配。在你的例子中,如果fileNamestr有任何特殊的正则表达式字符(例如*,+,.等),那么你将会非常惊讶。使这个解决方案像正确的Contains功能一样工作的唯一方法是通过执行fileNamestr来逃避Regex.Escape(fileNamestr)
      2013-02-03 15:18:36Z
    2. 醇>

    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;
        }
    }
    
        
    34
    2011-01-25 06:58:32Z
    1. 为什么你允许超过StringComparison的另一层抽象?
      2019-06-20 18:37:30Z
    2. 醇>

    OrdinalIgnoreCase,CurrentCultureIgnoreCase还是InvariantCultureIgnoreCase?

    由于缺少这个,以下是关于何时使用哪一个的一些建议:

    待办事项

    • 使用StringComparison.OrdinalIgnoreCase进行比较 作为与文化无关的字符串匹配的安全默认值。
    • 使用StringComparison.OrdinalIgnoreCase比较 提高速度。
    • 使用StringComparison.CurrentCulture-based字符串操作 在向用户显示输出时。
    • 根据不变量切换当前字符串操作的使用 当比较为
      时,使用非语言StringComparison.OrdinalStringComparison.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

        
    24
    2015-07-23 10:30:30Z
    1. 如果你知道你总会得到一个英文字符串怎么办?哪一个使用?
      2017-03-23 23:43:53Z
    2. @ BKSpurgeon我会使用OrdinalIgnoreCase,如果情况无关
      2017-03-24 08:09:08Z
    3. 醇>

    仅限.NET Core 2.0+(截至目前)

    自从2.0版以来,.NET Core已经有了一对处理这个问题的方法:
    • String.Contains(Char, StringComparison
    • String.Contains(String, StringComparison

    示例:

     
    "Test".Contains("test", System.StringComparison.CurrentCultureIgnoreCase);
    

    随着时间的推移,他们可能会进入.NET标准,并从那里进入基类库的所有其他实现。

        
    19
    2018-11-08 14:49:03Z
    1. 最后!花了很长时间才有空......
      2019-02-12 16:33:08Z
    2. 醇>

    这些是最简单的解决方案。

    1. 按索引

       
      string title = "STRING";
      
      if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
      {
          // contains 
      }
      
    2. 通过改变案例

       
      string title = "STRING";
      
      bool contains = title.ToLower().Contains("string")
      
    3. By Regex

       
      Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
      
    12
    2018-07-12 09:25:53Z
    1. Greate,感谢第一个例子!!!
      2019-02-26 12:43:36Z
    2. 醇>

    我知道这不是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");
    
        
    10
    2011-09-09 13:55:07Z
    1. 你也知道它是如何在内部工作的吗?
      2013-03-18 08:12:42Z
    2. 醇>

    如果您对国际化存在担忧(或者您可以重新实现),那么VisualBasic程序集中的InStr方法是最好的。在它看来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);
    }
    
        
    10
    2013-12-06 14:11:23Z

    就像这样:

     
    string s="AbcdEf";
    if(s.ToLower().Contains("def"))
    {
        Console.WriteLine("yes");
    }
    
        
    10
    2016-07-19 19:23:43Z
    1. 这不是特定于文化的,在某些情况下可能会失败。应该使用culture.CompareInfo.IndexOf(paragraph,word,CompareOptions.IgnoreCase)。
      2014-07-22 07:50:47Z
    2. 为什么在进行不区分大小写的字符串比较时要避免使用string.ToLower()? Tl; Dr 这是昂贵的,因为新的字符串是”制造的“。
      2016-10-10 10:00:29Z
    3. 醇>

    使用此:

     
    string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);
    
        
    9
    2013-07-08 08:10:58Z
    1. 问题ner正在寻找Contains而不是Compare
      2011-07-11 08:05:29Z
    2. @ DuckMaestro,接受的答案是用Contains实现IndexOf。所以这种方法同样有用! 此页面上的C#代码示例正在使用string.Compare() 。 SharePoint团队的选择就是!
      2013-01-05 10:07:01Z
    3. 醇>

    使用RegEx是一种直接的方法:

     
    Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
    
        
    6
    2016-07-19 19:23:19Z
    1. 你的回答与guptat59完全相同,但正如他的答案所指出的,这将匹配正则表达式,所以如果你正在测试的字符串包含任何特殊的正​​则表达式字符,它不会产生所需的结果。
      2013-12-09 22:55:24Z
    2. 这是此答案的直接副本,并且受到影响来自该答案中所述的相同问题
      2016-10-10 10:04:01Z
    3. Downvote出于同样的原因@Liam给出了
      2017-10-21 04:28:02Z
    4. 同意。研究正则表达式
      2017-12-26 05:14:32Z
    5. 醇>

    这与此处的其他示例非常相似,但我决定将枚举简化为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) )
    ....
    
        
    5
    2015-10-17 07:46:58Z
     
    if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}
    
        
    2
    2016-10-26 14:34:14Z

    您可以使用string.indexof ()功能。这将不区分大小写

        
    2
    2016-12-11 13:41:20Z

    这里的技巧是寻找字符串,忽略大小写,但保持完全相同(使用相同的情况)。

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

    输出为“重置”

        
    2
    2017-10-31 15:16:18Z

    为了建立在这里的答案,你可以创建一个字符串扩展方法,使这个用户更友好:

     
        public static bool ContainsIgnoreCase(this string paragraph, string word)
        {
            return new CultureInfo("en-US").CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
        }
    
        
    1
    2019-02-14 08:53:57Z
    1. 假设您的段落和单词将始终位于en-US
      2019-02-15 13:42:59Z
    2. 为避免将文化强制为en-US,请改用return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
      2019-06-13 21:42:44Z
    3. 醇>
     
    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
    }
    
        
    0
    2017-06-14 03:16:07Z

    如果你想检查你传递的字符串是否在字符串中,那么有一个简单的方法。

     
    string yourStringForCheck= "abc";
    string stringInWhichWeCheck= "Test abc abc";
    
    bool isContaines = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;
    
    This boolean value will return if string contains or not
    
        
    0
    2017-11-16 12:23:46Z

    新手的简单方法:

     
    title.ToLower().Contains("string");//of course "string" is lowercase.
    
        
    - 4
    2018-03-23 03:33:44Z
    1. 这不能完全解决问题。
      2017-06-23 12:49:26Z
    2. Downvote表示错误。如果title = StRiNg怎么办? StRiNg!= string and StRiNg!= STRING
      2017-10-21 04:30:54Z
    3. 我错了。编辑答案如下,简单太简单:&lt; br /&gt; title.ToLower()。包含(“string”)//当然“string”是小写
      2018-03-23 03:28:07Z
    4. 醇>
    来源放置 这里