Я бы, вероятно, подошел к этому как к задаче разбиения на фрагменты и использовал бы часть речевого тега nltk
в сочетании с его фрагментом регулярного выражения. Это позволит вам определить регулярное выражение, основанное на части речи слов в ваших предложениях, а не на самих словах. Для данного предложения вы можете сделать следующее:
import nltk
# example sentence
sent = 'send me a table with a price greater than $100'
Первое, что я хотел бы сделать, это немного изменить ваши предложения, чтобы вы не слишком путали часть речевого теггера. Вот несколько примеров изменений, которые вы можете внести (с помощью очень простых регулярных выражений), но вы можете поэкспериментировать и посмотреть, есть ли другие:
$10 -> 10 dollars
200lbs -> 200 lbs
5-7 -> 5 - 7 OR 5 to 7
так получаем:
sent = 'send me a table with a price greater than 100 dollars'
теперь вы можете получить части речи из своего предложения:
sent_pos = nltk.pos_tag(sent.split())
print(sent_pos)
[('send', 'VB'), ('me', 'PRP'), ('a', 'DT'), ('table', 'NN'), ('with', 'IN'), ('a', 'DT'), ('price', 'NN'), ('greater', 'JJR'), ('than', 'IN'), ('100', 'CD'), ('dollars', 'NNS')]
Теперь мы можем создать блокировку, которая разбивает текст с тегами POS в соответствии с (относительно) простое регулярное выражение:
grammar = 'NumericalPhrase: {<NN|NNS>?<RB>?<JJR><IN><CD><NN|NNS>?}'
parser = nltk.RegexpParser(grammar)
Это определяет синтаксический анализатор с грамматикой, который разбивает числовые фразы (то, что мы назовем вашим типом фразы). Он определяет вашу числовую фразу как: необязательное существительное, за которым следует необязательное наречие, за которым следует сравнительное прилагательное, предлог, число и необязательное существительное. Это всего лишь предложение о том, как вы можете определять свои фразы, но я думаю, что это будет намного проще, чем использовать регулярное выражение для самих слов.
Чтобы получить свои фразы, вы можете:
print(parser.parse(sent_pos))
(S
send/VB
me/PRP
a/DT
table/NN
with/IN
a/DT
(NumericalPhrase price/NN greater/JJR than/IN 100/CD dollars/NNS))
Или, чтобы получить только свои фразы, вы можете:
print([tree.leaves() for tree in parser.parse(sent_pos).subtrees() if tree.label() == 'NumericalPhrase'])
[[('price', 'NN'),
('greater', 'JJR'),
('than', 'IN'),
('100', 'CD'),
('dollars', 'NNS')]]
person
bunji
schedule
16.07.2017