Парсинг простого текста к некоторому структурированному объекту

Я работаю над парсингом простого текста и преобразованием его к парам "ключ-значение". Например, простой текст:

some_uninteresting_thing
key1 valueA, some_uninteresting_thing  valueB
key2 valueD
key3 some_uninteresting_thing  valueE 
key4 valueG(valueH, valueI)
key5 some_uninteresting_thing 

И возможные отображения:

 Map(

 key1 ->(valueA, valueB,valueC), 
 key2 ->(valueD, valueE),
 key3 ->(valueF)
 key4 ->(valueH, valueI)

 ...
 )

Результат AMD будет:

key1 ->(valueA, valueB)
key2 ->(valueD)
key4 ->(valueH, valueI)

(key5 не должен быть отображен, потому что не имеет никаких соответствующих значений. Поскольку Вы видите, что простой текст снисходителен. Какая библиотека Java поможет обработать это?

5
задан Jeriho 27 April 2010 в 17:26
поделиться

2 ответа

Если вы знакомы с формальными языками, лексемами / грамматиками и т. Д., Вы можете использовать генератор парсеров, например JavaCC . JavaCC берет файл грамматики, который вы пишете, и генерирует Java-код, который анализирует текстовый файл на серию токенов или дерево синтаксиса. Существуют плагины для Maven и Ant, которые могут помочь интегрировать этот дополнительный источник в вашу сборку.

Для решения только во время выполнения есть RunCC , который я использовал с хорошими результатами. (Я подозреваю, что это не так быстро, как JavaCC, но в моем случае производительность была хорошей.)

Существует также Chaperon , который преобразует простой текст в XML, используя файл грамматики.

Альтернативой этому является использование специального сочетания регулярного выражения и StringTokenizer .

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

  1. напишите грамматику для вашего простого текстового файла. Некоторые подробности о вашем текстовом формате отсутствуют, но вы можете просто использовать BufferedReader.readLine () для чтения строк файла и StringTokenizer для разделения строки в подстроки через пробелы и запятые.
  2. Строки, которые вы получаете от синтаксического анализатора, первая строка, которую вы используете в качестве ключа, и последующие строки - это значения, которые вы добавляете в карту. Например. в псевдокоде

    Map> map = new HashMap> (); для каждой строки { List tokens = ...; // результат разделения строки String key = tokens.get (0); map.add (key, tokens.sublist (1, tokens.size ()); {{1} }}

    Даже если парсер не фильтрует неинтересный текст, он будет отфильтрован позже.

  3. Создайте синтаксический анализатор с вышеуказанными проектами для анализа формата файла карты. Опять же, вы можете создать простой синтаксический анализатор с регулярными выражениями и StringTokenizer. Используйте парсер для построения карты. Карта имеет ту же сигнатуру, что и выше, то есть Map >.

  4. Наконец, отфильтруйте входную карту по карте допустимых значений.

Что-то вроде этого.

   Map<String,List<String>> input = ...; // from step 1.
   Map<String,List<String>> allowed = ...; // from step 3.
   Map<String,List<String>> result = new HashMap<String<list<String>>(); // the final map
   for (String key : input.keySet()) {
      if (allowd.contains(key)) {
         List<String> outputValues = new ArrayList();
         List<String> allowedValues = allowed.get(key);
         List<String> inputValues = input.get(key);
         for (String value: inputValues) {
            if (allowedValues.contains(value))
                outputValues.add(value);
         }
         if (!outputValues.isEmpty())
            output.put(key, outputValues);
      }
   }
   // final result in filter
3
ответ дан 15 December 2019 в 06:20
поделиться

Вы можете использовать Интерпретатор и Строитель.

Интерпретатор анализирует источник и определяет ключи и значения, которые передаются Строителю, который создает любую структуру данных, которую вы хотите.

0
ответ дан 15 December 2019 в 06:20
поделиться
Другие вопросы по тегам:

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