有没有办法使以下返回为真?
string title = "ASTRINGTOTEST";
title.Contains("string");
似乎没有允许我设置区分大小写的过载。目前我将它们都大写,但这很愚蠢(我指的是上下大小写带来的 i18n 问题)。
更新
这个问题很古老,从那时起,我意识到如果您愿意全面调查,我会要求一个非常广泛而困难的主题的简单答案。
在大多数情况下,在单语英语代码库中,this 答案就足够了。我怀疑是因为大多数来这里的人都属于这一类,这是最受欢迎的答案。
This 但答案带来了一个固有问题,即我们无法比较不区分大小写的文本,除非我们知道两个文本是相同的文化并且我们知道该文化是什么。这可能是一个不太受欢迎的答案,但我认为它更正确,这就是我将其标记为这样的原因。
您可以使用 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;
}
}
请注意,null propagation ?.
自 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);
测试字符串 paragraph
是否包含字符串 word
(感谢@QuarterMeister)
culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0
其中 culture
是描述文本所用语言的 CultureInfo
实例。
此解决方案对于不区分大小写的定义是透明的,这取决于语言。例如,英语将字符 I
和 i
用于第九个字母的大写和小写版本,而土耳其语将这些字符用于其 29 个字母长的字母表中的 eleventh and twelfth letters。土耳其语大写版本的“i”是不熟悉的字符“İ”。
因此,字符串 tin
和 TIN
是相同的单词 英语,但不同的单词 土耳其语。据我了解,一个意思是“精神”,另一个是象声词。 (土耳其人,如果我错了,请纠正我,或者提出一个更好的例子)
总而言之,您只能回答“这两个字符串是否相同但在不同情况下”的问题如果您知道文本的语言。如果你不知道,你将不得不采取一个平底船。鉴于英语在软件方面的霸权,您可能应该求助于 CultureInfo.InvariantCulture
,因为它会以熟悉的方式出错。
culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0
?它使用正确的文化并且不区分大小写,它不分配临时的小写字符串,并且避免了转换为小写和比较是否总是与不区分大小写的比较相同的问题。
您可以像这样使用 IndexOf()
:
string title = "STRING";
if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
// The string exists in the original
}
由于 0(零)可以是一个索引,因此您检查 -1。
如果找到该字符串,则 value 的从零开始的索引位置,否则为 -1。如果 value 为 String.Empty,则返回值为 0。
使用正则表达式的替代解决方案:
bool contains = Regex.IsMatch("StRiNG to search", Regex.Escape("string"), RegexOptions.IgnoreCase);
RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant;
。
"This is a sample string that doesn't contain the search string"
中搜索 "."
。或者尝试搜索 "(invalid"
。
Regex.Escape
可能会有所帮助。当 IndexOf
/ extension Contains
很简单(并且可以说更清晰)时,Regex 似乎仍然没有必要。
.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 的一部分,因此是实现此版本标准(或更高版本)的基类库的所有实现的一部分。
您总是可以先将字符串向上或向下转换。
string title = "string":
title.ToUpper().Contains("STRING") // returns true
哎呀,刚刚看到最后一点。无论如何,不区分大小写的比较*
可能*
会做同样的事情,如果性能不是问题,我认为创建大写副本并比较它们没有问题。我可以发誓我曾经看过一次不区分大小写的比较......
答案的一个问题是,如果字符串为空,它将引发异常。您可以将其添加为支票,这样它就不会:
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;
}
if (string.IsNullOrEmpty(source)) return string.IsNullOrEmpty(toCheck);
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
上允许另一个抽象层?
这是干净和简单的。
Regex.IsMatch(file, fileNamestr, RegexOptions.IgnoreCase)
fileNamestr
有任何特殊的正则表达式字符(例如 *
、+
、.
等),那么您会大吃一惊。使此解决方案像正确的 Contains
函数一样工作的唯一方法是通过执行 Regex.Escape(fileNamestr)
来转义 fileNamestr
。
OrdinalIgnoreCase、CurrentCultureIgnoreCase 还是 InvariantCultureIgnoreCase?
由于缺少此功能,因此以下是有关何时使用哪一个的一些建议:
多斯
使用 StringComparison.OrdinalIgnoreCase 进行比较,作为与文化无关的字符串匹配的安全默认值。
使用 StringComparison.OrdinalIgnoreCase 比较来提高速度。
在向用户显示输出时使用基于 StringComparison.CurrentCulture 的字符串操作。
当比较在语言上不相关(例如,符号)时,切换当前使用基于不变区域性的字符串操作以使用非语言 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
这些是最简单的解决方案。
按字符串标题索引 = "STRING"; if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1) { // contains } 通过更改大小写 string title = "STRING"; bool contains = title.ToLower().Contains("string") 通过正则表达式 Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
简单而有效
title.ToLower().Contains("String".ToLower())
像这样:
string s="AbcdEf";
if(s.ToLower().Contains("def"))
{
Console.WriteLine("yes");
}
我知道这不是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");
如果您担心国际化(或者您可以重新实现它),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);
}
您可以使用字符串比较参数(可从 .NET Core 2.1 及更高版本获得)String.Contains Method。
public bool Contains (string value, StringComparison comparisonType);
例子:
string title = "ASTRINGTOTEST";
title.Contains("string", StringComparison.InvariantCultureIgnoreCase);
用这个:
string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);
Contains
而不是 Compare
。
IndexOf
实现 Contains
。所以这种方法同样有用! this page 上的 C# 代码示例使用 string.Compare()。 SharePoint 团队的选择就是!
这与此处的其他示例非常相似,但我决定将 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) )
....
只是为了建立这里的答案,您可以创建一个字符串扩展方法以使其更加用户友好:
public static bool ContainsIgnoreCase(this string paragraph, string word)
{
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
}
return CultureInfo.CurrentCulture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0;
。
使用 RegEx 是一种直接的方法:
Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
如果你想检查你传递的字符串是否在字符串中,那么有一个简单的方法。
string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";
bool isContained = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;
如果字符串被包含或不包含,这个布尔值将返回
类似于以前的答案(使用扩展方法),但有两个简单的空检查(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 当然可以作为参数发送。
评分最高的几个答案都以他们自己的方式很好和正确,我写在这里是为了添加更多信息、上下文和观点。
为了清楚起见,让我们考虑如果 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+00e9 = U+0065 U+0301 = U+00c9 = U+0045 U+0301 = U+0049 = U+0065 = E = e = É = é
Kanatype 敏感或不敏感,即您可以将日语平假名和片假名视为等效或不同。这两个音节包含相同数量的字符,以(大部分)相同的方式组织和发音,但书写方式不同,用途不同。例如,片假名用于借词或外国名称,但平假名用于儿童读物、发音指南(例如红宝石),以及没有汉字的单词(或者可能作者不知道汉字,或认为读者可能不知道)。
全角或半角敏感 - 由于历史原因,日语编码包括某些字符的两种表示 - 它们以不同的大小显示。
合字是否等效:请参阅 https://en.wikipedia.org/wiki/Ligature_(writing) æ 是否与 ae 相同?它们具有不同的 Unicode 编码,重音字符也是如此,但与重音字符不同,它们看起来也不同。这让我们...
阿拉伯语表示形式对等 阿拉伯语写作具有优美的书法文化,其中相邻字母的特定序列具有特定的表示。其中许多已在 Unicode 标准中编码。我不完全理解规则,但在我看来它们类似于连字。
其他文字和系统:我对卡纳达语、马拉雅拉姆语、僧伽罗语、泰语、古吉拉特语、藏语或几乎所有未提及的数十或数百种文字一无所知。我假设他们对程序员有类似的问题,并且考虑到到目前为止提到的问题的数量和如此少的脚本,他们可能还有程序员应该考虑的其他问题。
这使我们摆脱了“编码”杂草。
现在我们必须输入“意义”杂草。
北京等于北京吗?如果不是,北京等于北京吗?如果不是,为什么不呢?是拼音拼音。
北京等于北京吗?如果不是,为什么不呢?这是韦德-吉尔斯的罗马化。
北京等于北京吗?如果不是,为什么不呢?
你为什么要这样做?
例如,如果您想知道两个字符串(A 和 B)是否可能指代同一地理位置或同一个人,您可能想问:
这些字符串可以是一组汉字序列的 Wade-Giles 或拼音表示吗?如果是这样,相应的集合之间是否有任何重叠?
这些字符串中的一个可能是汉字的西里尔字母转录吗?
这些字符串中的一个可能是拼音罗马化的西里尔字母音译吗?
这些字符串中的一个可能是英文名字的中国化的拼音罗马化的西里尔字母音译吗?
显然,这些都是难题,没有确定的答案,而且无论如何,答案可能会根据问题的目的而有所不同。
以一个具体的例子结束。
如果你是递送信件或包裹,显然北京、北京、北京和北京都是平等的。为此,它们都同样出色。毫无疑问,中国邮局认可许多其他选项,例如法语的 Pékin、葡萄牙语的 Pequim、越南语的 Bắc Kinh 和蒙古语的 Бээжин。
单词没有固定的含义。
文字是我们用来导航世界、完成任务以及与他人交流的工具。
虽然看起来像 equality
、Beijing
或 meaning
这样的词具有固定含义会有所帮助,但可悲的是它们没有。
然而,我们似乎不知何故得过且过。
TL;DR:如果你正在处理与现实有关的问题,在其所有模糊不清(模糊、不确定、缺乏明确的界限)中,每个问题基本上都有三个可能的答案:
大概
可能不是
也许
if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}
您可以使用 string.indexof ()
功能。这将不区分大小写
这里的诀窍是寻找字符串,忽略大小写,但保持完全相同(使用相同的大小写)。
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
}
根据现有答案和 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;
}
}
新手的简单方法:
title.ToLower().Contains("string");//of course "string" is lowercase.
paragraph.ToLower(culture).Contains(word.ToLower(culture))
和CultureInfo.InvariantCulture
相同的答案,但它不能解决任何本地化问题。为什么要把事情复杂化? stackoverflow.com/a/15464440/284795ToLower
版本包括 2 个分配,这在比较/搜索操作中是不必要的。为什么在不需要的场景中进行不必要的分配?string
是IEnumerable<char>
因此您不能使用它来查找子字符串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 */