разбиение строки на многосимвольный разделитель с использованием сопоставления с образцом

1

Я запускаю следующую простую программу:

public class TestClass {
    public static void main(final String[] args) {
        String valid = "abc|~abc|~abc|~abc|~abc|~|~|~|~|~|~|~abc";
        String invalid = "xyz|~xyz|~xyz|~xyz|~xyz|~|~|~|~|~|~|~";
        String delimiter = "|~";
        Pattern pattern = Pattern.compile(Pattern.quote(delimiter));
        String[] tokensValid = pattern.split(valid);
        String[] tokensInvalid = pattern.split(invalid);
        System.out.println("Valid: " + tokensValid.length);
        System.out.println("InValid: " + tokensInvalid.length);
    }
}

Выход:

Valid: 12
InValid: 5

Но я считаю, что выход должен быть:

Valid: 12
InValid: 12

Как это работает?

Теги:

2 ответа

3
Лучший ответ

Перегрузка one-arg из String.split отбрасывает все пустые пустые лексемы.

Этот метод работает как бы путем вызова метода разделения с двумя аргументами с заданным выражением и предельным аргументом нуля. Поэтому конечные пустые строки не включаются в результирующий массив.

У вас их 7. Вот почему вы получаете 5 для вашего дела "InValid".

Чтобы получить 12, вы должны использовать перегрузку с двумя аргументами String.split с отрицательным пределом (или пределом не менее 12), который не отбрасывает завершающие пустые токены.

Предельный параметр управляет количеством применений шаблона и, следовательно, влияет на длину результирующего массива. Если предел n больше нуля, шаблон будет применен не более n - 1 раз, длина массива будет не больше n, а последний элемент массива будет содержать все входные данные за пределами последнего сопоставленного разделителя. Если n не является положительным, шаблон будет применяться столько раз, сколько возможно, и массив может иметь любую длину. Если n равно нулю, шаблон будет применяться столько раз, сколько возможно, массив может иметь любую длину, а конечные пустые строки будут отброшены.

1

Из документации по методу split (акцент мой)

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

Другими словами, расщепление "xyz|~xyz|~xyz|~xyz|~xyz|~|~|~|~|~|~|~" на |~ будет начинаться с создания массива

["xyz","xyz","xyz","xyz","xyz","","","","","","",""]

но из-за того, что параметр limit в вызываемом внутреннем split(CharSequence input, int limit) был установлен на 0 удаленных пустых строк, удаленный, что означает, что массив результатов, который вы получили,

["xyz","xyz","xyz","xyz","xyz"]

который является длиной 5.

Основываясь на документации по этому методу, если вы хотите избежать удаления пустых строк, вы можете использовать этот метод с отрицательным значением limit например

String[] tokensInvalid = pattern.split(invalid, -1);
//                                              ^^^

Ещё вопросы

Сообщество Overcoder
Наверх
Меню