String.IndexOf() returns 意外的字符串索引
String.IndexOf() returns unexpected index of string
String.IndexOf() 方法未按预期运行。
我预计它找不到匹配项,因为确切的词 you 不在 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
的有效子串。如果您想查找某个单词是否在字符串中,您可以 parse the string with Split method.
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string[] words = text.Split(delimiterChars);
然后查看数组内部。或者把它变成更多的lookup-friendly数据结构。
如果您想搜索 case-insensitive 可以使用以下代码:
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"));
False
True
创建字典如下code-snippet您可以快速检查所有单词的所有位置。
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));
youR:
2
7
friend
3
8
您遇到的问题是因为 IndexOf
匹配较大字符串中的单个字符或字符序列(搜索字符串)。因此 "I am your friend" 包含序列 "you"。只匹配单词,就得从单词层面考虑。
例如,您可以使用正则表达式匹配单词边界:
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
,由于边界要求,它不会匹配 your
。
在正则表达式中查看有关单词边界的更多信息 here。
String.IndexOf() 方法未按预期运行。
我预计它找不到匹配项,因为确切的词 you 不在 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
的有效子串。如果您想查找某个单词是否在字符串中,您可以 parse the string with Split method.
char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string[] words = text.Split(delimiterChars);
然后查看数组内部。或者把它变成更多的lookup-friendly数据结构。
如果您想搜索 case-insensitive 可以使用以下代码:
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"));
False
True
创建字典如下code-snippet您可以快速检查所有单词的所有位置。
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));
youR: 2 7 friend 3 8
您遇到的问题是因为 IndexOf
匹配较大字符串中的单个字符或字符序列(搜索字符串)。因此 "I am your friend" 包含序列 "you"。只匹配单词,就得从单词层面考虑。
例如,您可以使用正则表达式匹配单词边界:
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
,由于边界要求,它不会匹配 your
。
在正则表达式中查看有关单词边界的更多信息 here。