1. 标准分词器StandardAnalyzer
在演示smartcn中文分词器之前,先来看看Lucene标准分词器对中文分词的效果。需要的jar为\lucene-5.5.5\core\下的lucene-core-5.5.5.jar和\lucene-5.5.5\analysis\common\下的lucene-analyzers-common-5.5.5.jar。新建测试类TestLucene04:package net.xxpsw.demo.lucene.test; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; public class TestLucene04 { private void print(Analyzer analyzer) throws Exception { String text = "Lucene自带多种分词器,其中对中文分词支持比较好的是smartcn。"; TokenStream tokenStream = analyzer.tokenStream("content", text); CharTermAttribute attribute = tokenStream.addAttribute(CharTermAttribute.class); tokenStream.reset(); while (tokenStream.incrementToken()) { System.out.println(new String(attribute.toString())); } } }增加测试方法testStandardAnalyzer:
/** * @Description: 测试标准分词器 * @throws Exception */ @Test public void testStandardAnalyzer() throws Exception { StandardAnalyzer standardAnalyzer = new StandardAnalyzer(); print(standardAnalyzer); }执行测试,控制台打印结果如下:
由上可见,标准分词器对中文的分词结果是分成了单个汉字,而并没有识别常用的汉语词组。
2. 中文分词器SmartChineseAnalyzer
引入\lucene-5.5.5\analysis\smartcn\下的lucene-analyzers-smartcn-5.5.5.jar,新增测试方法testSmartChineseAnalyzer:/** * @Description: 测试中文分词器 * @throws Exception */ @Test public void testSmartChineseAnalyzer() throws Exception { SmartChineseAnalyzer smartChineseAnalyzer = new SmartChineseAnalyzer(); print(smartChineseAnalyzer); }执行测试方法,控制台打印结果如下:
从上述打印结果中可以看到,“多种”、“分词”、“其中”、“中文”、“支持”、“比较”等中文词组都被顺利的识别出来。
进入SmartChineseAnalyzer源码中可以看到如下代码:
public SmartChineseAnalyzer() { this(true); }查看this(true):
public SmartChineseAnalyzer(boolean useDefaultStopWords) { stopWords = useDefaultStopWords ? DefaultSetHolder.DEFAULT_STOP_SET : CharArraySet.EMPTY_SET; }查看DefaultSetHolder.DEFAULT_STOP_SET:
private static class DefaultSetHolder { static final CharArraySet DEFAULT_STOP_SET; static { try { DEFAULT_STOP_SET = loadDefaultStopWordSet(); } catch (IOException ex) { // default set should always be present as it is part of the // distribution (JAR) throw new RuntimeException("Unable to load default stopword set"); } } static CharArraySet loadDefaultStopWordSet() throws IOException { // make sure it is unmodifiable as we expose it in the outer class return CharArraySet.unmodifiableSet(WordlistLoader.getWordSet(IOUtils .getDecodingReader(SmartChineseAnalyzer.class, DEFAULT_STOPWORD_FILE, StandardCharsets.UTF_8), STOPWORD_FILE_COMMENT)); } }查看DEFAULT_STOPWORD_FILE:
private static final String DEFAULT_STOPWORD_FILE = "stopwords.txt";可见SmartChineseAnalyzer的空构造函数实际上默认加载了一个停用词列表文件stopwords.txt,该文件在jar包中的位置如下:
该文件中包含了53个需要停用的标点符号,分别是,.`-_=?'|"(){}[]<>*#&^$@!~:;+/\《》—-,。、:;!·?“”)(【】[]●及中文空格。
3. 自定义停用词
SmartChineseAnalyzer还支持自定义停用词,新建测试方法testMySmartChineseAnalyzer:/** * @Description: 测试自定义停用词 * @throws Exception */ @Test public void testMySmartChineseAnalyzer() throws Exception { CharArraySet charArraySet = new CharArraySet(0, true); // 系统默认停用词 Iterator<Object> iterator = SmartChineseAnalyzer.getDefaultStopSet().iterator(); while (iterator.hasNext()) { charArraySet.add(iterator.next()); } // 自定义停用词 String[] myStopWords = { "对", "的", "是", "其中" }; for (String stopWord : myStopWords) { charArraySet.add(stopWord); } SmartChineseAnalyzer smartChineseAnalyzer = new SmartChineseAnalyzer(charArraySet); print(smartChineseAnalyzer); } }执行测试方法,控制台打印如下:
对比测试方法testSmartChineseAnalyzer可以看出,"对", "的", "是", "其中"等中文词已被停用而不再出现。