2014-01-24 6 views
2

Я хочу разобрать разделитель Отдельные значения с цитирующими символами и escape для цитирования.Как разобрать разделимое значение разделителя с указанными символами и выйти

Например: a, "b""c""", d -> Ожидается стричь как три колонки (a), (b"C"), (d), считая запятую в качестве разделителя, цитата, как процитировать характер и избежать характера.

Я хочу также поддерживать несколько разделителей и охватывающих символов.

Например: a, "b""c"""|d -> Ожидается, что у вас будет три столбца, если мы используем как запятую, так и |, используемые в качестве разделителя.

Другой пример: a, <b\<c\>>|d -> Ожидаемое разобрать как три колонки, если мы используем как запятая и | как разделители, < как левый корпус > в правом корпусе и \ как побег.

Возможно ли создать комбинатор парсера с использованием JParsec?

Проведя некоторое время с API, я ожидал, что ниже код работает, но он не работает, как ожидалось, для анализа вышеприведенного примера.

Parser<?> quote_content = Scanners.notAmong(rightEnclose).many(); 
Parser<?> quoted = Scanners.nestableBlockComment(Scanners.among(leftEnclose), 
      Scanners.among(rightEnclose), quote_content); 
Parser<?> unquoted = Scanners.notAmong(delimiter + leftEnclose); 
Parser<?> chunk = Parsers.or(escapedSequence(), unquoted); 

Parser<?> all = chunk().many1().source().sepBy(Scanners.among(delimiter)); 

Просьба предложить, используя JParsec, есть ли лучшая альтернатива?

+0

попробуйте использовать csvReader –

+0

Начал искать в JParsec для поддержки сценариев, таких как множественные разделители - либо запятая, либо | может использоваться как разделитель. – Satya

+0

Не можете добавить код для 'escapeSequence(), который отсутствует в вашем примере. Я дам ему попробовать сегодня (я являюсь поддерживающим jparsec ...) – insitu

ответ

0

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

@Test public void test() throws Exception { 
    Parser<Void> escapingDoubleQuotesString = pattern(regex("((\"\")|[^\",])*"), "string"); 
    Parser<String> quoted = escapingDoubleQuotesString // 
     .between(isChar('"'), isChar('"')).source() // 
     .map(unquoteString()); 

    assertThat(quoted.parse("\"\"\"c\"")).isEqualTo("\"c"); 

    Parser<String> unquoted = escapingDoubleQuotesString.source().map(unescapeQuotes()); 

    assertThat(unquoted.parse("\"\"c")).isEqualTo("\"c"); 

    Parser<List<String>> separated = quoted.or(unquoted).sepBy(pattern(regex("\\s*,\\s*"), "comma")); 

    assertThat(separated.parse("a,\"b\"\"c\"\"\", d")).containsExactly("a", "b\"c\"", "d"); 
    } 

    private Map<? super String, ? extends String> unescapeQuotes() { 
    return new Map<String, String>() { 
     @Override public String map(String s) { 
      return s.replace("\"\"", "\""); 
     } 
     }; 
    } 

    private Map<String, String> unquoteString() { 
    return new Map<String, String>() { 
     @Override public String map(String s) { 
      return unescapeQuotes().map(s.substring(1, s.length() - 1)); 
     } 
     }; 
    } 

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

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

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

  • Нет связанных вопросов^_^