Метод String.IndexOf () работает не так, как я ожидал.
Я ожидал, что совпадение не будет найдено, поскольку точного слова вы нет в str
.
string str = "I am your Friend";
int index = str.IndexOf("you",0,StringComparison.OrdinalIgnoreCase);
Console.WriteLine(index);
Выход: 5
Мой ожидаемый результат -1, потому что строка не содержит вас .
2 ответа
Проблема, с которой вы сталкиваетесь, заключается в том, что 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
.
Подробнее о границах слов читайте в Регулярных выражениях здесь.
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"));
Ложные
Правда
Создав словарь, как в следующем фрагменте кода, вы можете быстро проверить все позиции для всех слов.
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
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.