Странная работа StartsWith
Получаю тест из Excel файла.
protected override string TakeTextFromFile(string Path)
{
var workbook = new Workbook();
workbook.LoadFromFile(Path);
var sheet = workbook.Worksheets[0];
var temporaryFileName = Guid.NewGuid() + ".txt";
sheet.SaveToFile(temporaryFileName, " ", Encoding.UTF8);
var textFromFile = File.ReadAllText(temporaryFileName).Replace(@"\", "").Replace("\"", "").Split(new string[1] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
var result = "";
foreach (var text in textFromFile)
result += text;
return result;
}
Результат метода TakeTextFromFile передаю в метод SearchTextInText. SearchTextInText("qweqweqweqweqwадресячсчсясячсячс", "адрес"). Цель метода: найти количество вхождения строки в текст.
/// <summary>
/// Поиск текста в другом тексте
/// </summary>
/// <param name="TextForSearch">Текст, в котором будет происходить поиск</param>
/// <param name="SearchText">Текст, который нужно найти в тексте</param>
/// <returns></returns>
public static int SearchTextInText(string TextForSearch, string SearchText)
{
int findedCount = 0;
for(var i = 0; i < TextForSearch.Count(); i++)
{
var text = TextForSearch.Remove(0, i + 1);
if (text.StartsWith(SearchText))
findedCount++;
}
return findedCount;
}
Вывод метода SearchTextInText = 0, что есть неправильно.
Если конкретнее, то, когда переменная text в методе SearchTextInText становится равным адресячсчсясячсячс, условие в методе возвращает false.
До этого использовал Split и считал по количеству элементов в массиве. Результат тот же.
В чём проблема? Как можно переделать метод SearchTextInText?
Ответы (1 шт):
В чём проблема? Как можно переделать метод SearchTextInText?
Хоть ваша ошибка, скорее всего, не связана, с методом SearchTextInText, т.к. код метода я проверил на исполнение и его поведение не отличается от ожидаемого, но кое что исправить в нем все равно необходимо.
В цикле
for(var i = 0; i < TextForSearch.Count(); i++) { var text = TextForSearch.Remove(0, i + 1); if (text.StartsWith(SearchText)) findedCount++; }вы сразу удаляете первый символ и только потом проверяете начало строки, это приведет к тому, что если исходная строка начинается с искомой, это не будет обнаружено, т.к. первый символ вы уже отрезали. Исправить просто:
for(var i = 0; i < TextForSearch.Count(); i++) { //var text = TextForSearch.Remove(0, i + 1); var text = TextForSearch.Remove(0, i); if (text.StartsWith(SearchText)) findedCount++; }Вторая проблема в том, что ваш метод поиска генерирует массу мусорных объектов при удалении начальных символов, что создает ненужную дополнительную нагрузку по сборке мусора. И если в учебной программе это будет незаметно, т.к. она,скорее всего, закончит работу до первого обращения к GC, то в продуктовом варианте такое поведение неприемлемо.
public static int SearchTextInText(string TextForSearch, string SearchText) { int startidx = 0; int findIdx; int count = 0; while ((findIdx = TextForSearch.IndexOf(SearchText, startidx)) >= 0) { startidx = findIdx + 1; count++; } return count; }В таком варианте новые строки не генерируются, а сам поиск выполняется в нативном коде (реализацию IndexOf смотри в ILSpy или на refferencesource)