Python 如何使用SpaCy Matcher(或短语匹配器)类来提取2个项目的序列?

Python 如何使用SpaCy Matcher(或短语匹配器)类来提取2个项目的序列?,python,nlp,spacy,matcher,Python,Nlp,Spacy,Matcher,我有以下任务:从文本中提取两个标记的组合。他们每个人都属于这个名单。例如: colors=['red','gray','black','white','brown'] animals=['fox','bear','hare','squirrel','wolf'] SpaCy文档中描述了如何匹配两个列表中的所有这些单词或如何匹配特定两个单词的顺序,例如: pattern = [{"LOWER": "red"}, {"LOWER": &q

我有以下任务:从文本中提取两个标记的组合。他们每个人都属于这个名单。例如:

colors=['red','gray','black','white','brown']
animals=['fox','bear','hare','squirrel','wolf']
SpaCy文档中描述了如何匹配两个列表中的所有这些单词或如何匹配特定两个单词的顺序,例如:

pattern = [{"LOWER": "red"}, {"LOWER": "fox"}]
但我需要匹配任何组合,如“红松鼠”或“白熊”。 我可以通过SpaCy中的Matcher(或短语匹配器)来实现这一点吗?或者我需要使用任何其他python模块? 有人有非法解决的想法吗


提前感谢您的帮助。

您也可以在SpaCy中使用正则表达式。例如,
fr“(?i)^({'|'.join(colors)})$”
将创建一个模式,该模式以不区分大小写的方式匹配标记,该模式将匹配任何一个
颜色

import spacy
from spacy.matcher import Matcher

nlp = spacy.load("en_core_web_sm")

matcher = Matcher(nlp.vocab)

colors=['red','gray','black','white','brown']
animals=['fox','bear','hare','squirrel','wolf']
pattern = [
   {'TEXT': {"REGEX": fr"(?i)^({'|'.join(colors)})$"}},
   {'TEXT': {"REGEX": fr"(?i)^({'|'.join(animals)})$"}}
]
matcher.add("ColoredAnimals", None, pattern)

doc = nlp("Hello, red fox! Hello Black Hare! What's up whItE sQuirrel, brown wolf and gray bear!")
matches = matcher(doc)
for match_id, start, end in matches:
    string_id = nlp.vocab.strings[match_id]
    span = doc[start:end]
    print(match_id, string_id, start, end, span.text)
输出:

8757348013401056599 ColoredAnimals 2 4 red fox
8757348013401056599 ColoredAnimals 6 8 Black Hare
8757348013401056599 ColoredAnimals 12 14 whItE sQuirrel
8757348013401056599 ColoredAnimals 15 17 brown wolf
8757348013401056599 ColoredAnimals 18 20 gray bear
您可以使用正则表达式直接提取短语:

import re
colors=['red','gray','black','white','brown']
animals=['fox','bear','hare','squirrel','wolf']
pattern = fr"(?i)\b(?:{'|'.join(colors)})\s+(?:{'|'.join(animals)})\b"
doc_string = "Hello, red fox! Hello Black Hare! What's up whItE sQuirrel, brown wolf and gray bear!"
print ( re.findall(pattern, doc_string) )
# => ['red fox', 'Black Hare', 'whItE sQuirrel', 'brown wolf', 'gray bear']


在这里,使用非捕获组是为了不在结果列表中创建其他项,
\s+
匹配一个或多个空格字符,
\b
用作单词边界,而不是
^
(字符串开头)和
$
(字符串结尾)锚。

您可以退回到正则表达式,使用类似于
(fox | white){2}
(正则表达式:“fox”或“white”连续两次)谢谢。我考虑过使用正则表达式。我会努力的。Wiktor,谢谢你的精彩解决方案!我相信这是一个非常好的案例。至于我,我终于找到了只使用Matcher类及其属性来处理令牌列表的解决方案。@Victoria很高兴它对您有用。请考虑通过点击来接受答案。✓ 如果我的回答对你有帮助(请参见),请点击左边(请参见)并向上投票(请参见)。