如何实现任意起始偏移量的n-gram分词?以king martin为例
解决方案
首先明确:edge_ngram分词器只能从文本边缘(开头或结尾)生成连续子串,没法覆盖中间任意起始位置的子串,所以满足不了你的需求。要实现提取所有长度≥3的中间子串,分两种场景处理:
一、代码自定义生成(以Python为例)
如果是在代码里处理文本,直接遍历每个单词的所有可能起始位置,提取符合长度要求的子串即可。针对"king martin"的实现代码如下:
text = "king martin" min_length = 3 result = [] for word in text.split(): word_len = len(word) # 遍历每个起始索引 for start in range(word_len): # 遍历从min_length到剩余长度的所有子串长度 for length in range(min_length, word_len - start + 1): end = start + length substring = word[start:end] result.append(substring) # 去重并排序(可选操作) result = sorted(list(set(result))) print(result)
运行后会得到:['kin', 'king', 'ing', 'mar', 'mart', 'marti', 'martin', 'art', 'arti', 'artin', 'rti', 'rtin', 'tin']
完全覆盖你需要的中间子串和完整单词。
二、搜索引擎中使用ngram分词器(以Elasticsearch为例)
如果是在Elasticsearch这类系统里处理,放弃edge_ngram,直接用ngram分词器——它会生成文本中所有连续子串,不受起始位置限制。
配置示例:
{ "settings": { "analysis": { "analyzer": { "custom_ngram_analyzer": { "tokenizer": "custom_ngram_tokenizer" } }, "tokenizer": { "custom_ngram_tokenizer": { "type": "ngram", "min_gram": 3, "max_gram": 6 # 对应最长单词martin的长度 } } } } }
用这个分析器处理"king martin",得到的分词结果就是所有长度3到6的子串,包含你需要的kin、ing、mar等中间子串。
内容的提问来源于stack exchange,提问作者toch
相关产品推荐
相关产品推荐

