Разбор простого текста в некотором структурированном объекте - PullRequest
5 голосов
/ 26 апреля 2010

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

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)

 ...
 )

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

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

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

Ответы [ 2 ]

3 голосов
/ 29 апреля 2010

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

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

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

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

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

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

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

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

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

  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
0 голосов
/ 26 апреля 2010

Вы можете использовать переводчика и строителя.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...