使用 spacy 匹配器提取括号内的所有数据

Extract all the data within parenthesis using spacy matcher

我正在尝试使用 spacy 匹配器从括号内提取数据。

假设文本是:'我在 Whosebug(x 年),我在这里问有关自然语言处理 (NLP)(信息检索)的(技术)问题'

匹配器的期望输出是:(x 年),(技术)(NLP)(信息检索)

下面是我尝试使用的代码

nlp = spacy.load("en_core_web_sm")
text = 'I am on Whosebug(for x years) and I ask (technical) questions here about Natural Language Processing (NLP) (information retrieval)'
doc = nlp(text)
matcher = Matcher(nlp.vocab)
pattern = [{"ORTH": '(', }, {"TEXT": {"REGEX": r".*?"}}, {"ORTH": ')'}]
matcher.add('paranthesis_data', None, pattern)
matches = matcher(doc)
for match_id, start, end in matches:
   print(nlp.vocab.strings[match_id], doc[start:end])

我得到的输出如下:

但我想要这样的输出: 数据(x 年) 数据(技术) 数据(自然语言处理) 数据(信息检索)

我知道我可以使用正则表达式,但这在我的项目中不是一个选项。如果我使用 'OP' 它会返回很长的字符串匹配,例如:(x 年)我问(技术)

非常感谢任何帮助,我将不胜感激。

在 Matcher 模式中,REGEX 匹配单个标记,而不是整个文档的文本。它没有按照您的意愿行事。

我想你可以用这样的模式得到你想要的:

pattern = [{"TEXT": '(', }, {"TEXT": {"NOT_IN": [")"]}, "OP": "*"}, {"TEXT": ')'}]

其他几个问题...

字符串 Whosebug(for(注意缺少 space)可能是单个标记。如果这是一个常见问题,您需要调整分词器来处理它。

您似乎在使用 v2 样式的 Matcher 代码。 spaCy v3 已经推出一年了,如果你正在开始一个新项目,我建议你升级。

另见 the rule-based matching docs