Как разобрать файл в INI / JSON-подобном нестандартном формате? - PullRequest
1 голос
/ 17 января 2012

Предположим, у меня есть текстовый файл в следующем (нестандартном) формате:

xxx { a = v1; b = v2 }
yyy { a = v3; c = v4 } 

Я не могу изменить его на какой-либо стандартный (INI / XML / YAML и т. Д.) Формат.

Теперь я хотел бы найти значение свойства a в разделе xxx (то есть v1).Какой самый простой способ сделать это в Java / Groovy?

Ответы [ 4 ]

3 голосов
/ 18 января 2012

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

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

Сделав это, вы можете найти готовый анализатор, который может справиться с вашим форматом.Если вам повезет, он может быть достаточно близок к INI, или JSON, или YAML, или к чему-то еще, чтобы соответствующий синтаксический анализатор работал (в основном).

Но есть вероятность, что это не так, и вынужно написать свой собственный парсер.Это можно сделать разными способами, например:

  • Вы можете разбить файл на строки и «проанализировать» каждую строку с помощью регулярного выражения.
  • Вы можете проанализировать файл, используяa Сканер с соответствующими разделителями.
  • Вы можете использовать генератор синтаксического анализатора для реализации лексера и анализатора.
  • Вы можете реализовать простой лексер и анализатор вручную.
  • Естьвероятно, конкретные решения Groovy.

На самом деле правильный выбор зависит от того, насколько простым или сложным является действительный формат.Мы не можем сказать это на одном примере.

3 голосов
/ 17 января 2012

С Groovy вы можете использовать ConfigSlurper.

Однако сначала вам нужно будет взломать карту действительных значений вместе, чтобы не удушать попытки выяснить, что такое v1, v2, v3, etc:

Кажется, это работает:

def input = '''xxx { a = v1; b = v2 }
              |yyy { a = v3; c = v4 }'''.stripMargin()

def slurper = new ConfigSlurper()

// Find all words 'w' and make a map of [ w1:'w1', w2:'w2', ... ]
slurper.binding = ( ( input =~ /\w+/ ) as List ).collectEntries { w -> [ (w):w ] }

def result = slurper.parse( input )
println result

Это выводит на печать:

[xxx:[a:v1, b:v2], yyy:[a:v3, c:v4]]

(Groovy 1.8.4)

2 голосов
/ 17 января 2012

Вероятно, не будет готового решения, если вы работаете с нестандартным форматом.Вот несколько подходов, которые вы, возможно, захотите рассмотреть:

  • , если формат прост, напишите пользовательский анализатор рекурсивного спуска
  • напишите фильтр для преобразования вашегоотформатируйте в INI, JSON и т. д. и используйте существующие библиотеки
  • , создайте groovy DSL , который соответствует вашему формату, и выполните свой файл как groovy-скрипт
  • используйте генератор синтаксического анализатораинструмент типа antlr или с пропаркой для создания анализатора из спецификации языка
2 голосов
/ 17 января 2012

Для настоящего файла формата INI: Какой самый простой способ анализа файла INI в Java?

То, что вы здесь показываете, для меня больше похоже на формат JSON, чем на INI. Возможно, посмотрите на библиотеки синтаксического анализа JSON. Правда в том, что вы не используете установленный формат, поэтому вы, вероятно, не будете использовать синтаксический анализатор установленного формата. Лучше всего, вероятно, реорганизовать файл, с которым вы имеете дело (если это возможно), в хорошо известный формат для начала. Не пытайтесь изобретать велосипед, если вам это не нужно.

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