2010-04-26 3 views
5

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

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 поможет справиться с этим?

+1

В случае, если линия, как 'ключ1 значение а, VALUE млрд, valueC' карте до 1 пара ключ/значение ('ключ1' => 'значение а, VALUE млрд, valueC') или 3 пары ключ/значение ('ключ1' = > 'valueA' и 'key1' => 'valueB и' key1 '=>' valueC ')? –

+1

Как ваш код обрабатывает первую строку вашего примера? Является ли 'some_uninteresting_thing' ключом без значения, или что? И как это должно быть учтено при обработке последней строки? –

+3

Как можно различать «неинтересный» текст и «интересный текст». Например, если первая строка «это жизнь, Джим», это неинтересно или это ключ = «это», значение А = «жизнь», значение Б = «Джим»? –

ответ

3

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

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

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

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

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

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

    Карта map = new HashMap>(); для каждой строки { Список токенов = ...; // результат разделения строки Строка key = tokens.get (0); map.add (ключ, 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

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

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

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

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