Соответствие буквенно-цифровой строки в грамматике nltk

Я пытаюсь использовать алгоритмы грамматики и анализа синтаксиса NTLK, поскольку они кажутся довольно простыми в использовании. Хотя, я не могу найти способ правильно соответствовать буквенно-цифровой строке, например:

import nltk grammar = nltk.parse_cfg (""" # Is this possible? TEXT -> \w* """) parser = nltk.RecursiveDescentParser(grammar) print parser.parse("foo") 

Есть ли простой способ достичь этого?

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

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

 import re import nltk from nltk.grammar import Nonterminal, Production, ContextFreeGrammar grammar = nltk.parse_cfg (""" S -> TEXT TEXT -> WORD | WORD TEXT | NUMBER | NUMBER TEXT """) productions = grammar.productions() def literal_production(key, rhs): """ Return a production <key> -> n :param key: symbol for lhs: :param rhs: string literal: """ lhs = Nonterminal(key) return Production(lhs, [rhs]) def parse(text): """ Parse some text. """ # extract new words and numbers words = set([match.group(0) for match in re.finditer(r"[a-zA-Z]+", text)]) numbers = set([match.group(0) for match in re.finditer(r"\d+", text)]) # Make a local copy of productions lproductions = list(productions) # Add a production for every words and number lproductions.extend([literal_production("WORD", word) for word in words]) lproductions.extend([literal_production("NUMBER", number) for number in numbers]) # Make a local copy of the grammar with extra productions lgrammar = ContextFreeGrammar(grammar.start(), lproductions) # Load grammar into a parser parser = nltk.RecursiveDescentParser(lgrammar) tokens = text.split() return parser.parse(tokens) print parse("foo hello world 123 foo") 

Вот еще информация о том, где это обсуждалось в группе nltk-users в группах google: https://groups.google.com/d/topic/nltk-users/4nC6J7DJcOc/discussion