2015-03-28 2 views
1

У меня есть дерево синтаксиса, сохраненное в текстовом файле в стиле LISP, с открытыми и закрытыми скобками, которые показывают отношения. Я хочу удалить все листья. Например, у меня есть «(Det the)», что я хочу стать «Det». Я не специалист по регулярному выражению, поэтому мне интересно, как я мог бы справиться с этим поведением в более сложной структуре с вложенными скобками. Пример дерева (в моем файле находится в одной строке, отступ только для более простой визуализации):Удалить листья в дереве с регулярным выражением (Python)

(S 
    (NP I) 
    (VP 
    (VP (V shot) (NP (Det an) (N elephant))) 
    (PP (P in) (NP (Det my) (N pajamas))))) 

я бы что-то вроде:

(S NP 
    (VP 
    (VP V (NP Det N)) 
    (PP P (NP Det N)))) 

ответ

1

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

re.sub("\((\w*) (\w*)\)", r"\1", t) 

где t - переменная, удерживающая ваше синтаксическое дерево.

Для поддержки Unicode см. Комментарии ниже.

+0

Это именно то, что мне нужно! Я попросил бы вас немного больше помочь, если это возможно: мне нужно иметь поддержку с символом Юникода, я сделал небольшой тест, и, например, «è», естественно, не обнаружен \ w (это только [a-z]). Как я могу справиться с этим? –

+1

@AndreaRomagnoli: См. [Re.UNICODE] (https://docs.python.org/2/library/re.html?highlight=re#re.UNICODE) в документах 're' Python. –

+0

Большое спасибо! –

3

Это следует сделать это:

import re 

tree1 = """(S 
    (NP I) 
    (VP 
    (VP (V shot) (NP (Det an) (N elephant))) 
    (PP (P in) (NP (Det my) (N pajamas)))))""" 

tree2 = re.sub("\(\s*(\w+)\s*(\w+)\s*\)", r"\1", tree1) 

print(tree2) 

Выход:

(S 
    NP 
    (VP 
    (VP V (NP Det N)) 
    (PP P (NP Det N)))) 

Это, вероятно, было бы лучше использовать \s* вместо всего (пространства) в регулярных выражениях - это позволит вам иметь последовательности нулевых или более пробельных символов (пробелы, табуляции и символы новой строки) в подстроках, представляющих листья.

link to online Python repl

link to regex101.com

+0

Так же, как и для новых строк,' \ s * 'допускает кратные любые символы пробела (простые пробелы, вкладки, новые строки и т. Д.), в строке, которая также может пригодиться. :) См. Запись для '\ s' в разделе [Синтаксис регулярного выражения] (https://docs.python.org/2/library/re.html?highlight=re#regular-expression-syntax) в Python' re 'docs для деталей. –

+0

Хорошо, теперь объясняется значение '\ s' и' * '. – Radek

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