Разделите строку на запятых, не содержавших в двойных кавычках со скручиванием

Я задал этот вопрос ранее, и он был закрыт, потому что это был дубликат, который я принимаю и на самом деле нашел ответом в Java вопроса: разделение разделенной от запятой строки, но игнорирование запятых в кавычках, таким образом, благодаря тому, кто бы ни отправил его.

Но я с тех пор столкнулся с другой проблемой. По-видимому, то, что я должен сделать, использовать"" как мой разделитель, когда существует нуль или четное число двойных кавычек, но также и игнорируют любого"", содержал в скобках.

Так следующее:

"Thanks,", "in advance,", "for("the", "help")"

Маркировал бы как:

  • Спасибо,
  • заранее,
  • для ("справка")

Я не уверен, должен ли там так или иначе изменить текущий regex, я использую для обеспечения этого, но любое руководство ценилось бы.

line.split(",(?=([^\"]*\"[^\"]*\")*[^\"]*$)");

12
задан Community 23 May 2017 в 11:44
поделиться

2 ответа

Иногда проще подобрать то, что нужно, а не то, что не нужно:

String s = "\"Thanks,\", \"in advance,\", \"for(\"the\", \"help\")\"";
String regex = "\"(\\([^)]*\\)|[^\"])*\"";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while(m.find()) {
    System.out.println(s.substring(m.start(),m.end()));
}

Output:

"Thanks,"
"in advance,"
"for("the", "help")"

Если вам также нужно, чтобы он игнорировал закрывающие скобки внутри секций кавычек, которые находятся внутри скобок, то вам нужно следующее:

 String regex = "\"(\\((\"[^\"]*\"|[^)])*\\)|[^\"])*\"";

Пример строки, которой нужна вторая, более сложная версия:

 "foo","bar","baz(":-)",":-o")"

Output:

"foo"
"bar"
"baz(":-)",":-o")"

Однако я бы посоветовал вам изменить формат данных, если это вообще возможно. Это было бы намного проще, если бы вы использовали стандартный формат, например XML, для хранения токенов.

5
ответ дан 2 December 2019 в 22:51
поделиться

Парсер домашнего производства легко пишется.

Например, эта грамматика ANTLR без проблем справится с вашим примером:

parse
  :  line*
  ;

line
  :  Quoted ( ',' Quoted )* ( '\r'? '\n' | EOF )
  ;

Quoted
  :  '"' ( Atom )* '"'
  ;

fragment
Atom
  :  Parentheses
  |  ~( '"' | '\r' | '\n' | '(' | ')' )
  ;

fragment
Parentheses
  :  '(' ~( '(' | ')' | '\r' | '\n' )* ')'
  ;

Space
  :  ( ' ' | '\t' ) {skip();}
  ;

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

При подаче парсера, сгенерированного этой грамматикой, на следующие две строки ввода:

"Thanks,", "in advance,", "for("the", "help")"
"and(,some,more)","data , here"

он будет разобран следующим образом:

alt text

Если вы решите использовать ANTLR для этого, я могу опубликовать небольшое HOW-TO для получения парсера из той грамматики, которую я разместил, если вы хотите.

3
ответ дан 2 December 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: