Метод String.IndexOf() работает не так, как я ожидал.
Я ожидал, что он не найдет совпадения, так как точного слова ты нет в str
.
string str = "I am your Friend";
int index = str.IndexOf("you",0,StringComparison.OrdinalIgnoreCase);
Console.WriteLine(index);
Выход: 5
Мой ожидаемый результат равен -1, потому что строка не содержит ты.
@bolkay Хотя Contains()
также сделает вывод, что «ты» находится в строке «Я твой друг».
Я тыr Друг... похоже, что это там для меня.. если вам нужны границы слов, используйте регулярное выражение или взломайте пробелы слева и справа от вашей строки поиска (однако, вероятно, вызовет больше проблем)
Я подозреваю, что вы хотите string.Split
разбить строку на слова. Тогда string.Compare
, а не string.IndexOf
.
если вы хотите сохранить большую часть своего кода, вы можете искать «вы» вместо «вы» (просто добавьте пробелы до и после строки «вы»)
@Dle Будет ли это работать для поиска начального I
?
хорошо, что @mjwills не подумал об этом, это не нашло бы «закрытия» ни у вас, ни у
А, я перепутал твой смысл. Я получаю 5, а ожидал 5. Строка определенно содержит «вы». Однако он не содержит «вы», но это другая строка.
да, Davesoft, вы поняли, поиск функции indexof содержит слово, я имею в виду, что слово «вы» не существует в строке, но все равно он вернет индекс 5, результаты должны быть -1
Я хочу найти позицию конкретного слова, поэтому из функции indexof я могу получить начальный индекс, но индекс дает неправильный индекс
you
является допустимой подстрокой I am your Friend
. Если вы хотите узнать, находится ли слово в строке, вы можете разобрать строку методом Split.
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"));
False
True
Создавая словарь, как в следующем фрагменте кода, вы можете быстро проверить все позиции для всех слов.
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
соответствует одному символу или последовательности символов (строке поиска) в большей строке. Поэтому «Я твой друг» содержит последовательность «ты». Чтобы сопоставлять только слова, вы должны рассматривать вещи на уровне слов.
Например, вы можете использовать регулярные выражения для сопоставления границ слов:
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
.
Подробнее о границах слов см. в разделе Регулярные выражения здесь.
Вы запрашиваете позицию последовательность символов «вы» в строке, а не позицию слово «вы» в строке. Так как «ваш» начинается с «вы», мы можем сделать вывод, что в строке есть последовательность символов «вы». документация указывает «Сообщает отсчитываемый от нуля индекс первого вхождения указанного символа Unicode или нить в этом экземпляре. Метод возвращает -1, если символ или строка не найдены в этом экземпляре».