我需要在 NLTK 的正则表达式解析器中创建一个非条件作为语法的一部分。我想分块那些结构为 'Coffee & Tea'
的词但如果有 <IN>
类型的词,它不应该分块在序列之前。例如'in London and Paris'
不应被解析器分块。
我的代码如下:
grammar = r'''NP: {(^<IN>)<NNP>+<CC><NN.*>+}'''
我尝试了上面的语法来解决问题,但它不起作用,有人可以告诉我我做错了什么吗。
例子:
def parse_sentence(sentence):
pos_sentence = nltk.pos_tag(nltk.word_tokenize(sentence))
grammar = r'''NP: {<NNP>+<CC><NN.*>+}'''
parser = nltk.RegexpParser(grammar)
result = parser.parse(pos_sentence)
print result
sentence1 = 'Who is the front man of the band that wrote Coffee & TV?'
parse_sentence(sentence1)
sentence2 = 'Who of those resting in Westminster Abbey wrote a book set in London and Paris?'
parse_sentence(sentence2)
Result for sentence 1 is:
(S
Who/WP
is/VBZ
the/DT
front/JJ
man/NN
of/IN
the/DT
band/NN
that/WDT
wrote/VBD
(NP Coffee/NNP &/CC TV/NN)
?/.)
Result for sentence2 is:
(S
Who/WP
of/IN
those/DT
resting/VBG
in/IN
Westminster/NNP
Abbey/NNP
wrote/VBD
a/DT
book/NN
set/VBN
in/IN
(NP London/NNP and/CC Paris/NNP)
?/.)
从 sentence1 和 sentence2 中可以看出短语 Coffee & Tea
和 London and Paris
尽管我不想分块 London and Paris
,但作为一个组进行分块.一种方法是忽略那些以 <IN>
开头的模式。 POS 标签。
简而言之,我需要知道如何在正则表达式解析器的语法中为 POS 标记添加 NOT(否定)条件。在标记定义后使用“^”的标准语法似乎不起作用
最佳答案
您需要的是一个“负面回顾”表达式。不幸的是,它在 block 解析器中不起作用,所以我怀疑你想要的东西不能指定为 block 正则表达式。
这是一个普通的负面回顾:匹配“Paris”,但如果前面有“and”则不匹配。
>>> re.findall(r"(?<!and) Paris", "Search in London and Paris etc.")
[]
不幸的是,相应的后视分块规则不起作用。 nltk 的 regexp 引擎会调整您传递给它的 regexp 以解释 POS 类型,它会被 lookbehinds 混淆。 (我猜 lookbehind 语法中的 <
字符被误解为标记定界符。)
>>> parser = nltk.RegexpParser(r"NP: {(?<!<IN>)<NNP>+<CC><NN.*>+}")
...
ValueError: Illegal chunk pattern: {(?<!<IN>)<NNP>+<CC><NN.*>+}
关于parsing - NLTK Regex Parser 中没有条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42731275/