Как разобрать параметры из текста? - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть текст, который выглядит так:

ENGINE = CollapsingMergeTree (
    first_param
    ,(
        second_a
        ,second_b, second_c,
        ,second d), third, fourth)

Движок может отличаться (вместо CollapsingMergeTree могут быть разные слова, ReplacingMergeTree, SummingMergeTree ...), но текст всегда имеет формат ENGINE = word (). Вокруг знака «=» может быть пробел, но это не обязательно. Внутри круглых скобок находятся несколько параметров, обычно одно слово и запятая, но некоторые параметры заключены в круглые скобки, как и второй в примере выше. Разрывы строк могут быть где угодно. Строка может заканчиваться запятой, скобкой или чем-то еще.

Мне нужно извлечь n параметров (я не знаю, сколько заранее). В приведенном выше примере есть 4 параметра:

  1. first = first_param

  2. second = (second_a, second_b, second_c, second_d) [извлечь с круглыми скобками]

  3. третий = третий

  4. четвертый = четвертый

Как это сделать с помощью Python (регулярные выражения или что-то еще)?

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

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

#Import the module for regular expressions
import re

#Text to search. I CORRECTED IT A BIT AS YOUR EXAMPLE SAID second d AND second_c WAS FOLLOWED BY TWO COMMAS. I am assuming those were typos.
text = '''ENGINE = CollapsingMergeTree (
    first_param
    ,(
        second_a
        ,second_b, second_c
        ,second_d), third, fourth)'''

#Regex search pattern. re.S means . which represents ANY character, includes \n (newlines)
pattern = re.compile('ENGINE = CollapsingMergeTree \((.*?),\((.*?)\),(.*?), (.*?)\)', re.S) #ENGINE = CollapsingMergeTree \((.*?),\((.*?)\), (.*?), (.*?)\)

#Apply the pattern to the text and save the results in variable 'result'. result[0] would return whole text.
#The items you want are sub-expressions which are enclosed in parentheses () and can be accessed by using result[1] and above
result = re.match(pattern, text)

#result[1] will get everything after theparenteses after CollapsingMergeTree until it reaches a , (comma), but with whitespace and newlines. re.sub is used to replace all whitespace, including newlines, with nothing
first = re.sub('\s', '', result[1])

#result[2] will get second a-d, but with whitespace and newlines. re.sub is used to replace all whitespace, including newlines, with nothing
second = re.sub('\s', '', result[2])

third = re.sub('\s', '', result[3])

fourth = re.sub('\s', '', result[4])

print(first)
print(second)
print(third)
print(fourth)

ВЫХОД:

first_param
second_a,second_b,second_c,second_d
third
fourth

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

\ (= убрать скобки

() = пометить выражение в скобках как подгруппу. См. Результат [1] и т. Д.

. = Соответствует любому символу (включая символ новой строки из-за re.S)

* = Соответствует 0 или более вхождений предыдущего выражения.

? = Соответствует 0 или 1вхождение предыдущего выражения.

ПРИМЕЧАНИЕ: *? комбинированный называется несжатым повторением, то есть предыдущее выражение сопоставляется только один раз, а не снова и снова.

Я не эксперт, ноНадеюсь, я правильно объяснил.

Надеюсь, это поможет.

0 голосов
/ 02 апреля 2019

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

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