Разбивка строк с сохранением разделителей в Java

Пройдите тест, узнайте какой профессии подходите и получите бесплатную карьерную консультацию
В конце подарим скидку до 55% на обучение
Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если вам необходимо разделить строку в Java, одновременно сохранив разделители, используйте класс Pattern с регулярными выражениями и утверждениями положительного просмотра вперед (?=regex) и положительного просмотра назад (?<=regex). Вот пример кода, в котором в качестве разделителя используется запятая:

Java
Скопировать код
String input = "Привет, мир! Как твои дела?";
String[] result = Pattern.compile("(?<=,)|(?=,)")
                         .splitAsStream(input)
                         .filter(s -> !s.isEmpty())
                         .toArray(String[]::new);

Если вам нужно использовать другой символ для разделителя, замените запятую на него.

Обработка динамических разделителей: String.format на практике!

Чтобы работать с переменными разделителями, можно использовать метод String.format, который позволяет вставлять разделитель в шаблон регулярного выражения:

Java
Скопировать код
String delimiter = ","; // Здесь ваш динамический разделитель
String pattern = String.format("(?<=%1$s)|(?=%1$s)", Pattern.quote(delimiter));
String[] result = Pattern.compile(pattern)
                         .splitAsStream(input)
                         .toArray(String[]::new);

Функция Pattern.quote(delimiter) обрабатывает разделитель как обычный текст, несмотря на любые специальные символы регулярных выражений, которые он может содержать.

Повышение читабельности сложных регулярных выражений

Чтобы сделать код более понятным и удобным для поддержки, старайтесь улучшить читабельность регулярных выражений. Вот пример:

Java
Скопировать код
String complexDelimiter = ",|;|\\.|!";
String pattern = String.format("(?<=%1$s)|(?=%1$s)", complexDelimiter);
String[] result = Pattern.compile(pattern)
                         .splitAsStream(input)
                         .toArray(String[]::new);

Переменная complexDelimiter здесь содержит несколько разделителей, что упрощает восприятие кода.

Визуализация

Разделение строки можно представить в виде разрезания пленки:

Markdown
Скопировать код
Оригинальная пленка: "Привет|Мир! Я здесь."

Разрезанная пленка: ["Привет", "|", "Мир!", " Я здесь."]

Метод split() в этом случае действует как ножницы:

Java
Скопировать код
String[] parts = input.split("(?<=\\|)|(?=\\|)");

Таким образом, каждый разделитель превращается в отдельный кадр фильма.

Pattern и Matcher: Ваши помощники в преобразовании строк

Если String.split() кажется вам слишком простым, попробуйте классы Pattern и Matcher:

Java
Скопировать код
Pattern pattern = Pattern.compile("вашеРегулярноеВыражение");
Matcher matcher = pattern.matcher(input);
List<String> matchList = new ArrayList<>();

while (matcher.find()) {
    matchList.add(matcher.group());
}

Учет краевых случаев

Не забывайте учитывать пустые элементы в массиве. Это особенно важно для начала и конца массива:

Java
Скопировать код
.filter(s -> !s.isEmpty()) // Пропустите только непустые строки!

StringTokenizer: Сохраняем токены в целостности

С помощью класса StringTokenizer можно работать с разделителями без потерь:

Java
Скопировать код
StringTokenizer tokenizer = new StringTokenizer(input, delimiter, true);
while (tokenizer.hasMoreTokens()) { 
    matchList.add(tokenizer.nextToken());
}

Параметр true делает StringTokenizer возвращающим разделители в виде отдельных токенов.

Индивидуальность с использованием Splitter из библиотеки Guava

Для уникальной настройки процесса разделения используйте Splitter из библиотеки Guava:

Java
Скопировать код
Iterable<String> parts = Splitter.on(pattern)
                                 .trimResults()
                                 .omitEmptyStrings()
                                 .split(input);

Упрощение сложности: Возвращение к основам с помощью replace

Иногда самый простой подход является самым правильным:

Java
Скопировать код
input = input.replace(delimiter, delimiter + "\0");
String[] parts = input.split("\0");

Используйте уникальные символы в качестве маркеров, чтобы безопасно разделить строку и сохранить ваши разделители.

Полезные материалы

  1. Метод split() строки в Java с примерами – GeeksforGeeks — подробные примеры разделения строк в Java.
  2. Matcher (Java Platform SE 7 ) — документация по методам appendReplacement и appendTail.
  3. Pattern (Java Platform SE 7 ) — документация по классу Pattern.
  4. String (Java Platform SE 7 ) — подробное описание метода String.split().
  5. Руководство по регулярным выражениям – Просмотр вперёд и назад без захватагид по утверждениям просмотра в регулярных выражениях.
  6. Регулярные выражения в Java – руководство — подробное описание Pattern и Matcher.
  7. Тестер и отладчик регулярных выражений онлайн – Javascript, PCRE, PHP — платформа для тестирования регулярных выражений в различных видах.