Получить подстроку между двумя другими строками?

#c#

#c#

Вопрос:

Я пытаюсь получить строку между двумя вложенными строками, но я сталкиваюсь с проблемой.

Я пытаюсь использовать Selenium для автоматизации веб-теста и извлечения идентификатора профиля из javascript в исходном коде страницы. Я сталкиваюсь с ArgumentOutOfRangeException ?

Это не имеет значения, когда я ищу правильные или неправильные значения и передаю их GetInbetween , это выдает это исключение. Я не вижу ничего плохого в своем коде, поэтому я здесь.

Код:

 var source = GetSource();
var username = "username1";

Console.WriteLine("Here: "   source.GetInbetween("window.__additionalDataLoaded('/"   username   "/',{"logging_page_id":"", "","));
  

Исходный код (усечен для удобства чтения):

 window.__additionalDataLoaded('/username1/',{"logging_page_id":"profilePage_10216","logging_page_username": "username1"})
  

Исключение:

 ArgumentOutOfRangeException 
Length cannot be less than zero. (Parameter 'length') 
  

Он выдает исключение в этом методе

 public static string GetInbetween(this string s, string start, string end)
{
    return s[(s.IndexOf(start)   start.Length)..s.IndexOf(end)];
}   
  

Тест LINQPad:

 void Main()
{
    var source = "window.__additionalDataLoaded('/username1/',{"logging_page_id":"profilePage_10216","logging_page_username":"username1"})";
    var username = "username1";
    
    Console.WriteLine(source.IndexOf("window.__additionalDataLoaded('/"   username   "/',{"logging_page_id":""));
    Console.WriteLine(source.IndexOf("","));
    
    Console.WriteLine($"[{source}]");
    Console.WriteLine($"[{"window.__additionalDataLoaded('/"   username   "/',{"logging_page_id":""}]");
    Console.WriteLine("Here: "   source.GetInbetween("window.__additionalDataLoaded('/"   username   "/',{"logging_page_id":"", ""."));
}
  

Комментарии:

1. В вашем коде LINQPad вы переходите ""," к IndexOf , чтобы получить результат 81, но вы переходите ""." к своему Getinbetween методу. Не в первом есть запятая, а во втором — точка. Если вы передадите значение с точкой IndexOf , результат будет равен -1.

Ответ №1:

Вы можете получить эту ошибку, если end существует s раньше start . Так что попробуйте использовать s.LastIndexOf(end) .

Комментарии:

1. @Milney Это наверняка выдало бы именно эту ошибку, как я подтвердил, используя .netfiddle ( dotnetfiddle.net/zvCEGK )

2. @Milney Если бы фрагмент был, скажем, между 8 и 3, результирующая длина была бы -5, что, я полагаю, могло бы вызвать такое исключение.

3. Использование LastIndexOf возвращает все после start .

4. Пример: profilePage_10216","logging_page_username": "username1"})

Ответ №2:

Он говорит ‘Длина не может быть меньше нуля.’ что означает, что indexOf возвращает -1, что и происходит, если подстрока не найдена в строке поиска… Итак, вы ищете подстроку, которая не существует в строке. Убедитесь, что вы правильно учитываете регистр, или используйте перегрузку indexOf, которая игнорирует регистр.

Редактировать — Ваш метод getSource() не должен возвращать строку, которую, по вашему мнению, он возвращает… Смотрите, отлично работает явный поиск по этой строке:

введите описание изображения здесь

Комментарии:

1. Обе подстроки существуют, я вручную подтвердил это. Чувствительность к регистру не имеет значения, поскольку javascript имеет тот же регистр, что и подстроки в коде, также подтвержденный вручную. Я попытаюсь отладить GetInbetween метод.

2. @AAA — вы подтвердили это неправильно, так как у меня это работает нормально — смотрите Мою правку. Попробуйте выполнить var source = «» и ввести его явно. Ваша функция getSource(), очевидно, возвращает не ту строку, о которой вы думаете

3. Я использовал строковый литерал для источника и получил эти результаты из indexOf (первый аргумент для GetInbetween и второй): 0 и 81

Ответ №3:

Передача начального индекса IndexOf(end) таким образом, похоже, исправляет это.

 return s[(s.IndexOf(start)   start.Length)..s.IndexOf(end, s.IndexOf(start))];
  

Окончательный метод выглядит следующим образом:

 public static string GetInbetween(this string s, string start, string end)
{
    return s[(s.IndexOf(start)   start.Length)..s.IndexOf(end, s.IndexOf(start))];
}
  

Комментарии:

1. Это не имело бы никакого значения, поскольку в вашем примере индекс start равен 0. Скорее всего, вы запустили это с правильным end значением, а не с опечаткой в опубликованном вами коде. Вам действительно следует проверить, возвращают ли оба вызова indexOf значение -1, и определить, как с этим справиться, а также в случае, когда end индекс предшествует start индексу плюс длина.