C# IndexOf()返回字符串的意外索引
String.IndexOf()方法未按预期运行 我希望它不会找到匹配项,因为确切的单词you不在C# IndexOf()返回字符串的意外索引,c#,.net,indexof,C#,.net,Indexof,String.IndexOf()方法未按预期运行 我希望它不会找到匹配项,因为确切的单词you不在str中 string str = "I am your Friend"; int index = str.IndexOf("you",0,StringComparison.OrdinalIgnoreCase); Console.WriteLine(index); 产出:5 我的预期结果是-1,因为字符串不包含youyou是I am your Friend的有效子字符串。如果你想知道一个单词是否在
str
中
string str = "I am your Friend";
int index = str.IndexOf("you",0,StringComparison.OrdinalIgnoreCase);
Console.WriteLine(index);
产出:5
我的预期结果是-1,因为字符串不包含you
you
是I am your Friend
的有效子字符串。如果你想知道一个单词是否在字符串中,你可以
然后查看阵列内部。或者将其转换为更易于查找的数据结构
如果要搜索不区分大小写的内容,可以使用以下代码:
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string text = "I am your Friend";
// HasSet allows faster lookups in case of big strings
var words = text.Split(delimiterChars).ToHashSet(StringComparer.OrdinalIgnoreCase);
Console.WriteLine(words.Contains("you"));
Console.WriteLine(words.Contains("friend"));
假真的
按照下面的代码片段创建字典,您可以快速检查所有单词的所有位置
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string text = "i am your friend. I Am Your Friend.";
var words = text.Split(delimiterChars);
var dict = new Dictionary<string, List<int>>(StringComparer.InvariantCultureIgnoreCase);
for (int i = 0; i < words.Length; ++i)
{
if (dict.ContainsKey(words[i])) dict[words[i]].Add(i);
else dict[words[i]] = new List<int>() { i };
}
Console.WriteLine("youR: ");
dict["youR"].ForEach(i => Console.WriteLine("\t{0}", i));
Console.WriteLine("friend");
dict["friend"].ForEach(i => Console.WriteLine("\t{0}", i));
您面临的问题是因为
IndexOf
匹配单个字符或较大字符串中的字符序列(搜索字符串)。因此,“我是你的朋友”包含序列“你”。为了只匹配单词,你必须在单词层次上考虑事物。
例如,可以使用正则表达式来匹配单词边界:
private static int IndexOfWord(string val, int startAt, string search)
{
// escape the match expression in case it contains any characters meaningful
// to regular expressions, and then create an expression with the \b boundary
// characters
var escapedMatch = string.Format(@"\b{0}\b", Regex.Escape(search));
// create a case-sensitive regular expression object using the pattern
var exp = new Regex(escapedMatch, RegexOptions.IgnoreCase);
// perform the match from the start position
var match = exp.Match(val, startAt);
// if it's successful, return the match index
if (match.Success)
{
return match.Index;
}
// if it's unsuccessful, return -1
return -1;
}
// overload without startAt, for when you just want to start from the beginning
private static int IndexOfWord(string val, string search)
{
return IndexOfWord(val, 0, search);
}
在您的示例中,您将尝试匹配\byou\b
,这是因为边界要求与您的
不匹配
查看有关正则表达式中单词边界的详细信息。您询问的是字符序列“You”在字符串中的位置,而不是单词“You”在字符串中的位置。由于“your”以“you”开头,我们可以得出结论,字符串中的字符序列是“you”。状态“报告此实例中第一次出现的指定Unicode字符或字符串的从零开始的索引。如果在此实例中未找到该字符或字符串,则该方法返回-1。”@bolkay Through
Contains()
也将得出“you”在字符串“I am your Friend”中的结论。I am your Friend。。。在我看来它就在那里。。如果您需要单词边界,请使用正则表达式,或在搜索字符串的左右空格中进行破解(但可能会导致更多问题),我怀疑您要做的是string.Split
将字符串拆分为单词。然后string。比较而不是string.IndexOf
。如果您想保留大部分代码,可以搜索“you”而不是“you”(只需在“you”字符串前后添加空格)
youR:
2
7
friend
3
8
private static int IndexOfWord(string val, int startAt, string search)
{
// escape the match expression in case it contains any characters meaningful
// to regular expressions, and then create an expression with the \b boundary
// characters
var escapedMatch = string.Format(@"\b{0}\b", Regex.Escape(search));
// create a case-sensitive regular expression object using the pattern
var exp = new Regex(escapedMatch, RegexOptions.IgnoreCase);
// perform the match from the start position
var match = exp.Match(val, startAt);
// if it's successful, return the match index
if (match.Success)
{
return match.Index;
}
// if it's unsuccessful, return -1
return -1;
}
// overload without startAt, for when you just want to start from the beginning
private static int IndexOfWord(string val, string search)
{
return IndexOfWord(val, 0, search);
}