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

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

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

似乎没有允许我设置大小写敏感性的重载。目前我将它们都大写,但这太愚蠢了(我指的是向上和向下大小写带来的国际化问题)。

更新

这个问题是古老的,从那时起,我意识到我要求一个简单的答案,一个非常广泛和困难的话题,如果你想充分调查它。

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

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

1130733 次浏览

你总是可以先向上或向下排列字符串。

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

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

您可以使用#0方法并传递#1作为要使用的搜索类型:

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

请注意,零传播?.自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);

你可以像这样使用IndexOf()

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

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

Microsoft. NET文档:

如果找到该字符串,则从当前实例开始的value参数的从零开始的索引位置,如果没有,则为-1。如果value为空,则返回值为start Index。

使用Regex的替代解决方案:

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

字符串扩展类是前进的方向,我结合了上面的几篇文章来给出一个完整的代码示例:

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

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

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

使用这个:

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

我知道这不是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)

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

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

其中culture#1的实例,描述了文本所用的语言。

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

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

总而言之,你只能回答“这两个字符串是相同的,但在不同的情况下”这个问题如果你知道文本是什么语言。如果你不知道,你将不得不赌一把。鉴于英语在软件领域的霸主地位,你可能应该求助于#0,因为它会以熟悉的方式出错。

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

Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);

如果你担心国际化(或者你可以重新实现它),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;elsereturn Utils.GetCultureInfo().CompareInfo.IndexOf(sSrc, sFind, lStartPos, CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth);}

普通IgnoreCase,当前文化IgnoreCase还是不变文化IgnoreCase?

由于缺少这一点,这里有一些关于何时使用哪一个的建议:

Dos

  • 使用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}

而[你的决定]取决于上面的建议。

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

就像这样:

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

这与这里的其他示例非常相似,但我决定将枚举简化为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) )....

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

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

如果字符串是否包含,此布尔值将返回

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

  1. 按索引

    string title = "STRING";
    if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1){// contains}
  2. By Changing case

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

    Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);

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

. NET Core自2.0版以来有一对方法来处理此问题:

  • 字符串.包含(Char,字符串类型
  • 包含(String,字符串类型

示例:

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

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

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

    public static bool ContainsIgnoreCase(this string paragraph, string word){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;}

如果source为null,则返回false(通过null传播运算符?)

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

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

基于现有的答案和包含方法的留档,我建议创建以下扩展,它也会处理角落情况:

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 Core 2.1及更高版本获得)字符串.包含方法

public bool Contains (string value, StringComparison comparisonType);

示例:

string title = "ASTRINGTOTEST";title.Contains("string", StringComparison.InvariantCultureIgnoreCase);

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

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

几十年来,字符串何时相等的问题一直被详细考虑。目前的大部分知识都封装在SQL排序规则中。Unicode正常形式接近其中的一个适当子集。但是除了SQL排序规则之外还有更多。

例如,在SQL归类中,您可以

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

    例如,é可以表示为U+00e9(预组合)或U+0065 U+0301(e与组合急性口音)。

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

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

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

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

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

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

  • 等效或不等效的连接:见https://en.wikipedia.org/wiki/Ligature_(写作)

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

    这让我们想到…

  • 阿拉伯文表示形式等效

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

  • 其他脚本和系统:我不知道坎纳达语、马拉雅拉姆语、僧伽罗语、泰语、古吉拉特语、藏语,或者几乎所有没有提到的几十个或几百个脚本。我假设他们对程序员有类似的问题,鉴于到目前为止提到的问题数量和这么少的脚本,他们可能还有程序员应该考虑的其他问题。

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

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

  • Beijing等于北京吗?如果不是,Bĕijīng等于北京吗?如果不是,为什么不?这是拼音罗马化。

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

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

你为什么要这么做?

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

  • 这些字符串可能是一组汉字序列的韦德-贾尔斯或拼音表示吗?如果是,相应的集合之间是否有重叠?

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

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

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

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

最后,举一个具体的例子。

  • 如果你投递信件或包裹,显然BeijingPekingBĕijīng北京都是平等的。为此,它们都是同样好的。毫无疑问,中国邮局承认许多其他选择,例如Pékin法文、Pequim葡萄牙文、Bắc Kinh越南文和Бээжин蒙古文。

单词没有固定的含义。

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

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

然而,我们似乎以某种方式混日子。

太长别读:如果你正在处理与现实有关的问题,在所有的模糊(模糊,不确定性,缺乏明确的边界)中,基本上每个问题都有三种可能的答案:

  • 大概吧
  • 大概不会吧
  • 也许吧