IKAnalyzer 中文分词的不同版本切词方式

2020-12-24 09:59:33 浏览数 (1)

最近公司在做一个题库的功能,需要用到 中文分词和公式分词的工具,最开始用 IKAnalyzer 2012F 版本 lunece 6.5.1做了一版中文分词工具。具体如下:

一、IKAnalyzer 2012F lunece 6.5.1 实现中文分词

代码语言:javascript复制
	public static List<String> analysisByIK(Analyzer analyzer,String field, String content){
		if(StringUtils.isNullOrEmpty(content)){
			return null;
		}
		TokenStream ts = null;
		try {
			ts = analyzer.tokenStream(field, new StringReader(content));
			CharTermAttribute term = ts.addAttribute(CharTermAttribute.class);
			ts.reset(); 
			List<String> vocabularies = new ArrayList<>();
			while (ts.incrementToken()) {
				vocabularies.add(term.toString());
			}
			ts.end();
			return vocabularies;
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			if (ts != null) {
				try {
					ts.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}

调用方式:

代码语言:javascript复制
		String str = "已知三角形ABC中,角A等于角B加角C,那么三角形ABC是 A、锐角三角形 B、直角三角形 C、钝角三角形 D、不能确定";
		Analyzer analyzer = new IKAnalyzer(true);
		ikList  = analysisByIK(analyzer, "myfield", str);
		listAnalyzer.addAll(ikList);

输出结果listAnalyzerd:

代码语言:javascript复制
[已知, 三角形, abc, 中, 角, a, 等于, 角, b, 加, 角, c, 那么, 三角形, abc, 是, a, 锐角三角形, b, 直角三角形, c, 钝角三角形, d, 不能, 确定]

但是由于公式切词是 原来公司大牛写的,在满足公式切词的条件下,中文切词的IKAnalyzer 2012F与其不兼容。于是尝试其他版本,最终决定用 IKAnalyzer 3.2.8 实现了兼容。

二、IKAnalyzer 3.2.8 lunece 3.1.0 兼容版本

代码语言:javascript复制
	public static List<String> analysisByIK3Point2(Analyzer analyzer,String field, String content) throws Exception{
		if(StringUtils.isNullOrEmpty(content)){
			return null;
		}
		List<String> list = new ArrayList<>();
		Reader reader = new StringReader(content);
        TokenStream stream = (TokenStream)analyzer.tokenStream(field, reader);
        //添加工具类  注意:以下这些与之前lucene2.x版本不同的地方
        TermAttribute termAtt  = (TermAttribute)stream.addAttribute(TermAttribute.class);
        OffsetAttribute offAtt  = (OffsetAttribute)stream.addAttribute(OffsetAttribute.class);
        // 循环打印出分词的结果,及分词出现的位置
        while(stream.incrementToken()){
        	list.add(termAtt.term());
//              System.out.println(termAtt.term());
        }
		return list;
	}

调用方式:

代码语言:javascript复制
		String str = "已知三角形ABC中,角A等于角B加角C,那么三角形ABC是 A、锐角三角形 B、直角三角形 C、钝角三角形 D、不能确定";
		Analyzer analyzer = new IKAnalyzer(true);
		ikList  = analysisByIK3Point2(analyzer, "myfield", str);
		listAnalyzer.addAll(ikList);

输出结果:

代码语言:javascript复制
[已知, 三角形, abc, 中, 角, a, 等于, 角, b, 加, 角, c, 那么, 三角形, abc, 是, a, 锐角三角形, b, 直角三角形, c, 钝角三角形, d, 不能, 确定]

即使用不同版本实现相同功能效果。 主要是 因为IKAnalyzer 2012F 依赖Analyzer的tokenStream是final方法,但是公式分词用到的tokenSteam方法是抽象方法。两者冲突了,所以考虑去做兼容。

0 人点赞