Где метод split () в Java начинает сопоставление регулярного выражения со строкой?

Я возился с методом 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 начинает поиск совпадений с регулярным выражением? Или в чем именно состоит пробел в моих рассуждениях?

Number of matches + 1 'test' имеет 2 т, t дает 3. Тест имеет 4 символа, совпадение ничего не дает 5. Это то, что у вас есть?
user557597 18.03.2018 18:05

Также имейте в виду, что в более поздних версиях JDK метод split был оптимизирован так, что односимвольный шаблон, который не является специальным символом регулярного выражения, фактически не задействует механизм регулярного выражения. Таким образом, разделение только на символ «t» не приведет к задействованию регулярного выражения.

Bobulous 18.03.2018 18:09

Вы всегда можете установить ограничение на 0, что приведет к удалению любых пустых строк конечный из массива.

user557597 18.03.2018 18:15

@sln Да, я верю, что это могло случиться. Таким образом, по существу соответствие в "Z *" является синонимическим совпадением в пустой строке, и поскольку первая пустая строка идет после первого символа "test", было только 4 совпадения, что дает второму примеру длину 5?

NoobsPwnU 18.03.2018 18:16
Z* также будет соответствовать ничего такого, что эквивалентно "", если в семпле нет Z. Однако, если вы используете Z+ в строке без Z, вы должны получить массив из 1 элемента, исходную строку.
user557597 18.03.2018 18:19

@sln Хорошо, что ответил на мой вопрос. Большое спасибо! :)

NoobsPwnU 18.03.2018 18:20
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
165
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете прочитать исходный код jdk в Интернете. Вот раскол из OpenJdk 8.

String.split имеет оптимизацию счастливого пути для односимвольных строк, но большая часть работы делегируется Pattern.split. Разделение по шаблону имеет особый случай совпадения нулевой ширины в начале строки.

Другие вопросы по теме