String.IndexOf()返回字符串的意外索引

时间:2019-05-31 04:58:18

标签: 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,因为该字符串不包含

2 个答案:

答案 0 :(得分:7)

您面临的问题是因为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,由于边界要求,该匹配将不匹配your

Try it online

详细了解正则表达式here中的单词边界。

答案 1 :(得分:2)

youI am your Friend的有效子字符串。如果您想查找字符串中是否包含单词,可以parse the string with Split method.

char[] delimiterChars = { ' ', ',', '.', ':', '\t' };
string[] words = text.Split(delimiterChars);

然后查看数组内部。或将其变成对查询更友好的数据结构。

如果您要搜索不区分大小写的代码,可以使用以下代码:

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));
youR:   
        2   
        7   
friend   
        3   
        8