2016-03-07 5 views
8

Я должен разбить строку с помощью запятой (,) в качестве разделителя и игнорировать любую запятую, которая внутри кавычек (")
Java: Разбиваем строку с помощью Regex

fieldSeparator : ,
fieldGrouper : "

Строка для раскола: "1","2",3,"4,5"

Я могу достичь его следующим образом:

String record = "\"1\",\"2\",3,\"4,5\""; 
String[] tokens = record.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"); 

Выход:

"1" 
"2" 
3 
"4,5" 

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

Ожидаемый выход раскола:

1 
2 
3 
4,5 
+0

Я думаю, что делает этот символ-на-полукокса будет на самом деле более читабельным и определенно быстрее. И алгоритм так же прост, как и получается. И проще обработать исключение '' '', которое, скорее всего, появится рано или поздно. – Dariusz

+0

Можем ли мы спросить, почему вы работаете с неправильным вводом JSON? Фанкизм с цитатами затрудняет работу, и вам может быть лучше очистить источник. –

ответ

4

Update:

String[] tokens = record.split("(,*\",*\"*)");

Результат:
Image Link

Начальное решение:
(не работает @.split метод)

Этот RexEx шаблон изолирует разделы вы хотите:
(?:\\")(.*?)(?:\\")

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

Проверьте это здесь: Live Demo

+2

Это регулярное выражение не соответствует '3' или любым другим значениям, не заключенным в' '..." '. –

+0

@ WiktorStribiżew Я обновил решение, но в своем первоначальном решении я предположил, что шаблон '" # "' был последовательным. Я не понимал, что '3' не был захвачен, и все еще задаюсь вопросом, имеет ли у @rvd другой формат для' 3'. В любом случае, новое решение работает. – Enteleform

+0

Извините, но ваше второе разрешение не будет работать для ввода типа 1,2, когда 1 и 2 являются отдельными номерами. –

0

Мое предложение:

record = record.replaceAll("\",", "|"); 
record = record.replaceAll(",\\\"", "|"); 
record = record.replaceAll("\"", ""); 

String[] tokens = record.split("\\|"); 

for (String token : tokens) { 
    System.out.println(token); 
} 
2

Мое предложение:

"([^"]+)"|(?<=,|^)([^,]*) 

ВИДЕТЬ regex demo. Он будет соответствовать "...", как строки, и захватить в группу 1 только то, что находится между кавычками, а затем будет соответствовать и захватывать последовательности групп 2, отличные от ,, в начале строки или после запятой.

Вот Java sample code:

String s = "value1,\"1\",\"2\",3,\"4,5\",value2"; 
Pattern pattern = Pattern.compile("\"([^\"]+)\"|(?<=,|^)([^,]*)"); 
Matcher matcher = pattern.matcher(s); 
List<String> res = new ArrayList<String>(); 
while (matcher.find()){      // Run the matcher 
    if (matcher.group(1) != null) {   // If Group 1 matched 
     res.add(matcher.group(1));   // Add it to the resulting array 
    } else { 
     res.add(matcher.group(2));   // Add Group 2 as it got matched 
    } 
} 
System.out.println(res); // => [value1, 1, 2, 3, 4,5, value2] 
+0

. Лучше предположить, что он очищает исходные данные IMHO. –

1

Я хотел бы попробовать с этим видом обходной путь:

String record = "\"1\",\"2\",3,\"4,5\""; 
record = record.replaceAll("\"?(?<!\"\\w{1,9999}),\"?|\""," "); 
String[] tokens = record.trim().split(" "); 
for(String str : tokens){ 
    System.out.println(str); 
} 

Выход:

1 
2 
3 
4,5 
+0

Мне в конечном итоге пришлось использовать аналогичное обходное решение, то есть сначала расколоть, а затем удалить кавычки (если есть) из каждого токена. – rvd

Смежные вопросы