Избегайте запятых при использовании String.split - PullRequest
17 голосов
/ 11 февраля 2011

Я пытаюсь выполнить очень простой анализ файлов журнала, поэтому я использую String.split метод, подобный следующему:

String [] parts = input.split(",");

И прекрасно работает для ввода, например:

a,b,c

Или

type=simple, output=Hello, repeat=true 

Просто чтобы что-то сказать.

Как я могу избежать запятой, чтобы она не соответствовала промежуточным запятым?

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

type=simple, output=Hello, world, repeate=true

Я думал о чем-то вроде:

type=simple, output=Hello\, world, repeate=true

Но я не знаю, как создать разделение длястарайтесь не ставить запятую.

Я пробовал:

String [] parts = input.split("[^\,],");

Но, ну, не работает.

Ответы [ 4 ]

24 голосов
/ 11 февраля 2011

Вы можете решить это, используя отрицательный взгляд за .

String[] parts = str.split("(?<!\\\\), ");

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

String str = "type=simple, output=Hello\\, world, repeate=true";
String[] parts = str.split("(?<!\\\\), ");
for (String s : parts)
    System.out.println(s);

Вывод:

type=simple
output=Hello\, world
repeate=true

( ссылка ideone.com )


Если вы застряли снеэкранированные значения, разделенные запятыми, вы могли бы сделать следующее (похожее) взломать:

String[] parts = str.split(", (?=\\w+=)");

, который говорит разделение на каждом ", ", за которым следуют некоторые слова-символы и символ =

( ideone.com ссылка )

4 голосов
/ 11 февраля 2011

Боюсь, идеального решения для String.split не существует.Использование соответствия для трех частей будет работать.В случае, если количество деталей не является постоянным, я бы порекомендовал цикл с matcher.find.Примерно так может быть

final String s = "type=simple, output=Hello, world, repeat=true";
final Pattern p = Pattern.compile("((?:[^\\\\,]|\\\\.)*)(?:,|$)");
final Matcher m = p.matcher(s);
while (m.find()) System.out.println(m.group(1));

Возможно, вы захотите пропустить пробелы и после запятой:

final Pattern p = Pattern.compile("((?:[^\\\\,]|\\\\.)*)(?:,\\s*|$)");

Это не очень сложно, просто обратите внимание, что вам нужно четыре обратных слеша вчтобы соответствовать одному.

2 голосов
/ 11 февраля 2011

Escape работает с противоположным ответом aioobe (обновлено: aioobe теперь использует ту же конструкцию, но я не знал, что когда писал это), отрицательный взгляд позади

final String s = "type=simple, output=Hello\\, world, repeate=true";
final String[] tokens = s.split("(?<!\\\\),\\s*");
for(final String item : tokens){
    System.out.println("'" + item.replace("\\,", ",") + "'");
}

Выход:

Тип = простой '
'output = Hello, world'
'Repeate = истина'

Справка:

0 голосов
/ 11 февраля 2011

Я думаю

input.split("[^\\\\],");

должно работать. Он разделяется на все запятые, которым не предшествует обратный слеш. Кстати, если вы работаете с Eclipse, я могу порекомендовать плагин QuickRex для тестирования и отладки регулярных выражений.

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