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

執筆記憶的空白發表於2017-11-27


最近公司在做一個題庫的功能,需要用到 中文分詞和公式分詞的工具,最開始用 IKAnalyzer 2012F 版本 + lunece 6.5.1做了一版中文分詞工具。具體如下:


一、IKAnalyzer 2012F + lunece 6.5.1 實現中文分詞

	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;
	}

呼叫方式:

		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:

[已知, 三角形, abc, 中, 角, a, 等於, 角, b, 加, 角, c, 那麼, 三角形, abc, 是, a, 銳角三角形, b, 直角三角形, c, 鈍角三角形, d, 不能, 確定]




但是由於公式切詞是 原來公司大牛寫的,在滿足公式切詞的條件下,中文切詞的IKAnalyzer 2012F與其不相容。於是嘗試其他版本,最終決定用 IKAnalyzer 3.2.8 實現了相容。


二、IKAnalyzer 3.2.8 + lunece 3.1.0 相容版本

	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;
	}

呼叫方式:

		String str = "已知三角形ABC中,角A等於角B加角C,那麼三角形ABC是 A、銳角三角形 B、直角三角形 C、鈍角三角形 D、不能確定";
		Analyzer analyzer = new IKAnalyzer(true);
		ikList  = analysisByIK3Point2(analyzer, "myfield", str);
		listAnalyzer.addAll(ikList);

輸出結果:

[已知, 三角形, abc, 中, 角, a, 等於, 角, b, 加, 角, c, 那麼, 三角形, abc, 是, a, 銳角三角形, b, 直角三角形, c, 鈍角三角形, d, 不能, 確定]

即使用不同版本實現相同功能效果。 主要是 因為IKAnalyzer 2012F 依賴Analyzer的tokenStream是final方法,但是公式分詞用到的tokenSteam方法是抽象方法。兩者衝突了,所以考慮去做相容。




相關文章