Escape запятая при использовании String.split
Я пытаюсь выполнить некоторые простые простые обработки файлов журнала, поэтому я использую метод 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("[^\,],");
Но, ну, не работает.
Ответы
Ответ 1
Вы можете решить эту проблему, используя негативный внешний вид.
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+=)");
Который говорит, что раскол на каждом ", "
, за которым следуют некоторые слова-символы и an =
(ссылка ideone.com)
Ответ 2
Боюсь, нет идеального решения для 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*|$)");
Это не очень сложно, просто отметьте, что вам нужно четыре обратной косой черты, чтобы соответствовать одному.
Ответ 3
Escaping работает с противоположностью ответа aioobe (обновлено: aioobe теперь использует ту же конструкцию, но я не знал, что когда я это написал), negative lookbehind
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 = истина'
Справка:
Ответ 4
Я думаю,
input.split("[^\\\\],");
должен работать. Он будет разделен на все запятые, которые не преследуют обратную косую черту.
BTW, если вы работаете с Eclipse, я могу рекомендовать QuickRex Plugin для тестирования и отладки регулярных выражений.