String.split () - соответствует лидирующая пустая строка перед первым разделителем? - PullRequest
5 голосов
/ 28 апреля 2010

Мне нужно разделить входную строку запятыми, точками с запятой или пробелом (или смесью трех). Я также хотел бы рассматривать несколько последовательных разделителей во входных данных как один разделитель. Вот что у меня есть:

String regex = "[,;\\s]+";    
return input.split(regex);

Это работает, за исключением случая, когда входная строка начинается с одного из символов-разделителей, и в этом случае первый элемент массива результатов является пустой строкой. Я не хочу, чтобы в моем результате были пустые строки, поэтому что-то вроде ",,,, ZERO;, ;; ONE, TWO ;," возвращает только массив из трех элементов, содержащий заглавные строки.

Есть ли лучший способ сделать это, чем убрать любых ведущих символов, которые соответствуют моему reg-ex, до вызова String.split?

Заранее спасибо!

Ответы [ 4 ]

6 голосов
/ 28 апреля 2010

Нет, нет.Вы можете игнорировать только конечные разделители, указав 0 в качестве второго параметра для метода split () String:

return input.split(regex, 0);

, но для ведущих разделителей вам придется сначала удалить их:

return input.replaceFirst("^"+regex, "").split(regex, 0);
3 голосов
/ 28 апреля 2010

Если под «лучше» вы подразумеваете более высокую производительность, то вы можете попробовать создать регулярное выражение, которое соответствует тому, что вы хотите сопоставить, и использовать Matcher.find в цикле и извлекать совпадения по мере их нахождения. Это сохраняет изменение строки первым. Но измерьте это для себя, чтобы увидеть, что быстрее для ваших данных.

Если под «лучше» вы подразумеваете более простой, то нет, я не думаю, что есть более простой способ, чем тот, который вы предложили: удаление ведущих разделителей перед применением разбиения.

2 голосов
/ 29 апреля 2010

Практически все встроенные в JDK средства разбиения так или иначе сломаны. Вам было бы лучше использовать сторонний класс, такой как Splitter , который является гибким и правильным в том, как он обрабатывает пустые токены и пробелы:

Splitter.on(CharMatcher.anyOf(";,").or(CharMatcher.WHITESPACE))
    .omitEmptyStrings()
    .split(",,,ZERO;,ONE TWO");

даст итеративное , содержащее "НОЛЬ", "ОДИН", "ДВА"

1 голос
/ 28 апреля 2010

Вы также можете потенциально использовать StringTokenizer для построения списка, в зависимости от того, что вам нужно с ним делать:

StringTokenizer st = new StringTokenizer(",,,ZERO;,ONE TWO", ",; ", false);
while(st.hasMoreTokens()) {
  String str = st.nextToken();
  //add to list, process, etc...
}

Однако, как предостережение, вам нужно определить каждый потенциальный символ пробела отдельно во втором аргументе конструктора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...