基于近似词汇库的文本词汇提取算法:非子集匹配项的检测逻辑
目标词汇提取算法设计(忽略大小写)
核心思路
优先匹配最长的候选词汇,排除被更长匹配项完全包含的短词汇,只保留文本里实际出现的、未被覆盖的独立匹配项。
具体步骤
整理候选词汇库
- 把所有候选词汇转成小写(方便忽略大小写匹配),同时保留原大小写版本用于最终输出
- 按词汇的单词数量从多到少排序(用单词数量比字符长度更准确,避免长单词干扰),比如示例里的排序结果是:
Super Chicken Nuggets(3个单词)→Chicken Wings(2个)→Chicken Nuggets(2个)→Chicken(1个) - 同长度的词汇排序不影响最终结果
处理待匹配文本
- 把文本转成小写用于匹配,同时保留原文本(如果需要输出和文本里一致的大小写,就从原文本截取;如果只需要候选库的原大小写,这步可以简化)
按顺序匹配并标记已匹配区域
- 先建一个空集合,用来记录文本里已经被匹配的字符区间,防止重复匹配
- 按照排序后的候选词汇顺序逐个匹配:
- 对当前候选词的小写版本,在小写文本里找所有出现的位置
- 每个找到的位置,检查对应的字符区间有没有被之前的匹配覆盖过
- 如果没被覆盖,把匹配到的内容(原文本截取的或候选库原大小写版本)加入结果列表,同时把这个区间标记为已匹配
- 如果已经被覆盖,直接跳过(说明这个短词汇已经被更长的匹配项包含了)
整理最终结果
- 去掉结果里的重复项(如果有)
- 可以按词汇在原文本里的出现顺序重新排序结果(按需选择)
示例验证
示例1:待处理文本为 Instruction: Add super chicken nuggets and chicken wings to the salad
- 按规则排序候选词后,先匹配
Super Chicken Nuggets:在文本里找到对应片段,标记区间,加入结果 - 接着匹配
Chicken Wings:找到对应片段,未被标记,加入结果 - 匹配
Chicken Nuggets:它的文本区间已经被Super Chicken Nuggets覆盖,跳过 - 匹配
Chicken:所有可能出现的位置都被前两个匹配覆盖,跳过 - 最终提取结果:
Super Chicken Nuggets、Chicken Wings
示例2:待处理文本为 Add super chicken nuggets and chicken to the salad
- 同样先匹配
Super Chicken Nuggets,标记区间后加入结果 - 匹配
Chicken Wings:文本里没有这个内容,跳过 - 匹配
Chicken Nuggets:区间被Super Chicken Nuggets覆盖,跳过 - 匹配
Chicken:找到文本里独立的chicken片段,未被覆盖,加入结果 - 最终提取结果:
Super Chicken Nuggets、Chicken
实现小提示
- 用正则匹配时,可以加上
\b(单词边界),比如匹配\bchicken\b就不会误匹配super chicken nuggets里的chicken - 记录匹配位置时,可以用
(起始索引, 结束索引)的元组来标记区间,方便检查是否被覆盖 - 如果要严格保留文本里的大小写,匹配到位置后直接从原文本截取对应区间的内容即可
内容的提问来源于stack exchange,提问作者Jobo Fernandez
相关产品推荐
相关产品推荐

