3228

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

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

似乎没有允许我设置区分大小写的过载。目前我将它们都大写,但这很愚蠢(我指的是上下大小写带来的i18n问题)。

更新

这个问题很古老,从那时起,我意识到如果您愿意全面调查,我会要求一个非常广泛而困难的主题的简单答案。

在大多数情况下,在单语英语代码库中,这个答案就足够了。我怀疑是因为大多数来这里的人都属于这一类,这是最受欢迎的答案。

然而,这个答案带来了一个固有的问题,即在我们知道两个文本是相同的文化并且我们知道那种文化是什么之前,我们无法比较不区分大小写的文本。这可能是一个不太受欢迎的答案,但我认为它更正确,这就是我将其标记为这样的原因。

4

29 回答 29

2942

您可以使用String.IndexOfMethodStringComparison.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);
于 2009-01-14T21:44:11.623 回答
1536

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

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

描述文本所用语言culture的实例在哪里。CultureInfo

这个解决方案对于不区分大小写的定义是透明的,它是依赖于语言的。例如,英语使用字符Iandi表示第九个字母的大写和小写版本,而土耳其语使用这些字符表示其 29 个字母长的字母表中的第十一个和第十二个字母。土耳其语大写版本的“i”是不熟悉的字符“İ”。

因此,字符串tin在英语TIN中是同一个词,但在土耳其语中是不同的词。据我了解,一个意思是“精神”,另一个是象声词。(土耳其人,如果我错了,请纠正我,或者提出一个更好的例子)

总而言之,如果您知道文本的语言,您只能回答“这两个字符串是否相同但在不同情况下”的问题。如果你不知道,你将不得不采取一个平底船。鉴于英语在软件方面的霸主地位,您可能应该求助于CultureInfo.InvariantCulture,因为它会以熟悉的方式出错。

于 2013-03-17T18:22:11.727 回答
252

你可以IndexOf()这样使用:

string title = "STRING";

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

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

MSDN

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

于 2009-01-14T21:48:46.357 回答
156

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

bool contains = Regex.IsMatch("StRiNG to search", Regex.Escape("string"), RegexOptions.IgnoreCase);
于 2010-07-28T17:18:28.480 回答
138

.NET Core 2.0+(包括 .NET 5.0+)

自 2.0 版以来,.NET Core 有两种方法来处理这个问题:

  • String.Contains(Char, StringComparison )
  • String.Contains(字符串,字符串比较)

例子:

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

它现在正式成为 .NET Standard 2.1 的一部分,因此是实现此版本标准(或更高版本)的基类库的所有实现的一部分。

于 2018-10-13T09:26:54.980 回答
96

您总是可以先将字符串向上或向下转换。

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

哎呀,刚刚看到最后一点。无论如何,不​​区分大小写的比较可能**做同样的事情,如果性能不是问题,我认为创建大写副本并比较它们没有问题。我可以发誓我曾经看过一次不区分大小写的比较......

于 2009-01-14T21:42:37.273 回答
53

答案的一个问题是,如果字符串为空,它将引发异常。您可以将其添加为支票,这样它就不会:

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;
} 
于 2010-12-07T21:11:34.190 回答
40

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;
    }
}
于 2010-11-18T16:48:07.710 回答
35

这是干净和简单的。

Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)
于 2012-11-09T04:25:31.363 回答
32

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

于 2014-06-17T10:31:23.523 回答
25

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

  1. 按索引

    string title = "STRING";
    
    if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
    {
        // contains 
    }
    
  2. 通过更改大小写

    string title = "STRING";
    
    bool contains = title.ToLower().Contains("string")
    
  3. 通过正则表达式

    Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
    
于 2018-07-12T09:25:53.640 回答
19

简单而有效

title.ToLower().Contains("String".ToLower())
于 2019-12-10T22:32:51.050 回答
13

像这样:

string s="AbcdEf";
if(s.ToLower().Contains("def"))
{
    Console.WriteLine("yes");
}
于 2014-07-13T09:54:28.820 回答
11

我知道这不是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");
于 2011-09-09T13:23:12.973 回答
11

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);
}
于 2013-12-06T14:11:23.373 回答
10

用这个:

string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);
于 2011-07-11T07:53:22.780 回答
10

您可以使用字符串比较参数(可从 .net 2.1 及更高版本获得) String.Contains Method

public bool Contains (string value, StringComparison comparisonType);

例子:

string title = "ASTRINGTOTEST";
title.Contains("string", StringComparison.InvariantCultureIgnoreCase);
于 2021-01-07T19:42:35.587 回答
7

这与此处的其他示例非常相似,但我决定将 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) )
....
于 2015-10-17T07:46:58.717 回答
7

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

    public static bool ContainsIgnoreCase(this string paragraph, string word)
    {
        return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
    }
于 2019-02-14T08:53:57.880 回答
6

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

Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
于 2013-09-18T13:08:27.210 回答
5

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

string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";

bool isContained = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

如果字符串被包含或不包含,这个布尔值将返回

于 2017-11-16T12:23:46.303 回答
4

类似于以前的答案(使用扩展方法),但有两个简单的空检查(C# 6.0 及更高版本):

public static bool ContainsIgnoreCase(this string source, string substring)
{
    return source?.IndexOf(substring ?? "", StringComparison.OrdinalIgnoreCase) >= 0;
}

如果源为空,则返回假(通过空传播运算符?。)

如果 substring 为 null,则将其视为空字符串并返回 true(通过 null-coalescing operator ??)

如果需要,StringComparison 当然可以作为参数发送。

于 2020-07-13T12:02:26.480 回答
4

评分最高的几个答案都以自己的方式很好且正确,我写在这里是为了添加更多信息、上下文和观点。

为清楚起见,让我们考虑如果 A 中的任何代码点子序列等于 B,则字符串 A 包含字符串 B。如果我们接受这一点,问题就归结为两个字符串是否相等的问题。

几十年来,人们一直在详细考虑字符串何时相等的问题。许多当前的知识状态都封装在 SQL 排序规则中。Unicode 范式接近这个的真子集。但除了 SQL 排序规则之外,还有更多内容。

例如,在 SQL 排序规则中,您可以

  • 严格二进制敏感- 以便不同的 Unicode 规范化形式(例如预组合或组合重音)比较不同。

    例如,é可以表示为U+00e9(precombined) 或U+0065 U+0301(e with combined accent Accent)。

    这些是相同的还是不同的?

  • Unicode 标准化- 在这种情况下,上述示例将彼此相等,但不等于Éor e

  • 口音不敏感,(例如西班牙语、德语、瑞典语等文本)。在这种情况下U+0065= U+0065 U+0301= U+00e9= é=e

  • 不区分大小写和重音,以便(例如西班牙语、德语、瑞典语等文本)。在这种情况下U+00e9= U+0065 U+0301= U+00c9= U+0045 U+0301= U+0049= U+0065= E= e= É=é

  • Kanatypesensitive 或 insensitive,即您可以将日文平假名和片假名视为等效或不同。这两个音节包含相同数量的字符,以(大部分)相同的方式组织和发音,但书写方式不同,用途不同。例如,片假名用于借词或外国名称,但平假名用于儿童读物、发音指南(例如红宝石),以及没有汉字的单词(或者可能作者不知道汉字,或认为读者可能不知道)。

  • 全角或半角敏感- 由于历史原因,日语编码包括某些字符的两种表示 - 它们以不同的大小显示。

  • 合字是否等同:见https://en.wikipedia.org/wiki/Ligature_(writing)

    æ一样ae还是不一样?它们具有不同的 Unicode 编码,重音字符也是如此,但与重音字符不同,它们看起来也不同。

    这让我们...

  • 阿拉伯语表示形式等价

    阿拉伯文字具有优美的书法文化,其中相邻字母的特定序列具有特定的表示形式。其中许多已在 Unicode 标准中编码。我不完全理解规则,但在我看来它们类似于连字。

  • 其他文字和系统:我对卡纳达语、马拉雅拉姆语、僧伽罗语、泰语、古吉拉特语、藏语或几乎所有未提及的数十或数百种文字一无所知。我假设他们对程序员有类似的问题,并且考虑到到目前为止提到的问题的数量和如此少的脚本,他们可能还有程序员应该考虑的其他问题。

这使我们摆脱了“编码”杂草。

现在我们必须输入“意义”杂草。

  • 等于?Beijing_ 北京如果不是,Bĕijīng等于北京?如果不是,为什么不呢?是拼音拼音。

  • Peking等于北京? _ 如果不是,为什么不呢?这是韦德-吉尔斯的罗马化。

  • Beijing等于Peking? _ 如果不是,为什么不呢?

你为什么要这样做?

例如,如果您想知道两个字符串(A 和 B)是否可能指代同一地理位置或同一个人,您可能想问:

  • 这些字符串可以是一组汉字序列的 Wade-Giles 或拼音表示吗?如果是这样,相应的集合之间是否有任何重叠?

  • 这些字符串中的一个可能是汉字的西里尔字母转录吗?

  • 这些字符串中的一个可能是拼音罗马化的西里尔字母音译吗?

  • 这些字符串中的一个可能是英文名字的中国化的拼音罗马化的西里尔字母音译吗?

显然,这些都是难题,没有确定的答案,而且无论如何,答案可能会根据问题的目的而有所不同。

以一个具体的例子结束。

  • 如果您正在递送信件或包裹,显然, 和Beijing都是Peking平等的。为此,它们都同样出色。毫无疑问,中国邮局认可许多其他选项,例如法语、葡萄牙语、越南语和蒙古语。Bĕijīng北京PékinPequimBắc KinhБээжин

单词没有固定的含义。

文字是我们用来导航世界、完成任务以及与他人交流的工具。

虽然看起来像 , 或 具有固定含义的词会有所帮助equalityBeijingmeaning可悲的事实是它们没有。

然而,我们似乎不知何故得过且过。

TL;DR:如果你正在处理与现实有关的问题,在其所有模糊不清(模糊、不确定、缺乏明确的界限)中,每个问题基本上都有三个可能的答案:

  • 大概
  • 可能不是
  • 也许
于 2021-09-27T19:52:03.770 回答
3

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

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

输出是“重置”

于 2016-05-03T14:36:16.130 回答
3
if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}
于 2016-10-26T14:34:14.147 回答
3

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

于 2016-12-11T13:39:03.507 回答
1
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
}
于 2017-06-14T03:16:07.850 回答
0

根据现有答案和 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;
    }
}
于 2020-10-29T10:06:35.537 回答
-3

新手的简单方法:

title.ToLower().Contains("string");//of course "string" is lowercase.
于 2017-04-17T08:04:00.380 回答