Найпростіший підхід полягає в тому, щоб не співставити роздільники, тобто коми, зі складною додатковою логікою, щоб відповідати тому, що насправді призначено (дані, які можуть бути котировані рядками), а просто виключити помилкові роздільники, а скоріше співставити передбачувані дані.
Шаблон складається з двох альтернативних варіантів, рядка, що цитується ( "[^"]*"
або ".*?"
), або всього до наступної коми ( [^,]+
). Щоб підтримати порожні комірки, ми повинні дозволити порожній елемент, який не котирується, порожнім і спожити наступну кому, якщо така є, та використати \\G
якір:
Pattern p = Pattern.compile("\\G\"(.*?)\",?|([^,]*),?");
Шаблон також містить дві групи захоплення, щоб отримати будь-який, вміст рядка, що цитується, або звичайний вміст.
Тоді за допомогою Java 9 ми можемо отримати масив як
String[] a = p.matcher(input).results()
.map(m -> m.group(m.start(1)<0? 2: 1))
.toArray(String[]::new);
тоді як для старих версій Java потрібен цикл
for(Matcher m = p.matcher(input); m.find(); ) {
String token = m.group(m.start(1)<0? 2: 1);
System.out.println("found: "+token);
}
Додавання елементів до List
масиву чи масиву залишається читачем.
Для Java 8 ви можете використовувати results()
реалізацію цієї відповіді , щоб зробити це як рішення Java 9.
Для змішаного вмісту із вбудованими рядками, як у запитанні, ви можете просто використовувати
Pattern p = Pattern.compile("\\G((\"(.*?)\"|[^,])*),?");
Але потім рядки зберігаються в цитованому вигляді.
String line = "equals: =,\"quote: \"\"\",\"comma: ,\""
все, що вам потрібно зробити, це зняти сторонні подвійні лапки символів.