Я возился с методом split () в Java, когда столкнулся с проблемой, которую не мог понять. Мне было любопытно, где именно метод split начинает поиск совпадений с регулярным выражением: по первому символу, до или после?
Данная строка "test":
Если метод разделения начинается перед первым символом, тогда перед строкой «test» должна быть пустая строка, а разделение на пустую строку должно возвращать массив длиной 6, но длиной 5.
System.out.println("test".split("",-1).length);
Итак, очевидно, что метод разделения не запускается перед данной строкой.
Если метод разделения начинается с первого символа данной строки, то при разделении с регулярным выражением "Z *" не следует возвращать массив длиной 6 с начальной пустой строкой, поскольку первый символ действительно не Z (следовательно, 0 или более раз) ? Однако он возвращает массив длиной 5.
System.out.println("test".split("Z*",-1).length);
Итак, по индукции метод разделения начинается после первого символа ... но очевидно, что это не так, поскольку следующий код работает так, как ожидалось:
System.out.println("test".split("t",-1).length);
Output: 3
Итак, где именно метод split начинает поиск совпадений с регулярным выражением? Или в чем именно состоит пробел в моих рассуждениях?
Также имейте в виду, что в более поздних версиях JDK метод split был оптимизирован так, что односимвольный шаблон, который не является специальным символом регулярного выражения, фактически не задействует механизм регулярного выражения. Таким образом, разделение только на символ «t» не приведет к задействованию регулярного выражения.
Вы всегда можете установить ограничение на 0, что приведет к удалению любых пустых строк конечный из массива.
@sln Да, я верю, что это могло случиться. Таким образом, по существу соответствие в "Z *" является синонимическим совпадением в пустой строке, и поскольку первая пустая строка идет после первого символа "test", было только 4 совпадения, что дает второму примеру длину 5?
Z* также будет соответствовать ничего такого, что эквивалентно "", если в семпле нет Z. Однако, если вы используете Z+ в строке без Z, вы должны получить массив из 1 элемента, исходную строку.
@sln Хорошо, что ответил на мой вопрос. Большое спасибо! :)




Вы можете прочитать исходный код jdk в Интернете. Вот раскол из OpenJdk 8.
String.split имеет оптимизацию счастливого пути для односимвольных строк, но большая часть работы делегируется Pattern.split. Разделение по шаблону имеет особый случай совпадения нулевой ширины в начале строки.
Number of matches + 1'test' имеет 2 т,tдает 3. Тест имеет 4 символа, совпадение ничего не дает 5. Это то, что у вас есть?