参考文献:http://blog.csdn.net/fatpanda/article/details/37911079

jar包:

IK-Analyzer-extra-5.3.1.jar

IKAnalyzer5.3.1.jar

lucene-core-5.3.1.jar

lucene-analyzers-common-5.3.1.jar

一、创建类自己的分词器配置类并实现IK-Analyzer分词器的配置接口:

值得注意的一点是:我们在指定配置文件时候,要指定我们自己的配置文件。如果不指定路径默认会视作IKAnalyzer5.3.1.jar里面的IKAnalyzer.cfg.xml

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.InvalidPropertiesFormatException;
import java.util.List;
import java.util.Properties; import org.apache.commons.lang.StringUtils;
import org.wltea.analyzer.cfg.Configuration; public class MyConfiguration implements Configuration {
// 懒汉单例
private static final Configuration CFG = new MyConfiguration();
/*
* 分词器默认字典路径
*/
private String PATH_DIC_MAIN = "org/wltea/analyzer/dic/main2012.dic";// 需要把static final去掉
private static final String PATH_DIC_QUANTIFIER = "org/wltea/analyzer/dic/quantifier.dic";
/*
* 分词器配置文件路径
*/
private static final String FILE_NAME = "com/unruly/test/IKAnalyzer.cfg.xml";// 指定我们自己的分词器配置文件
// 配置属性——扩展字典
private static final String EXT_DICT = "ext_dict";
// 配置属性——扩展停止词典
private static final String EXT_STOP = "ext_stopwords"; private Properties props;
/*
* 是否使用smart方式分词
*/
private boolean useSmart; /**
* 返回单例
*
* @return Configuration单例
*/
public static Configuration getInstance() {
return CFG;
} /*
* 初始化配置文件
*/
MyConfiguration() {
props = new Properties(); InputStream input = this.getClass().getClassLoader().getResourceAsStream(FILE_NAME); if (input != null) {
try {
props.loadFromXML(input);
} catch (InvalidPropertiesFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
} /**
* 返回useSmart标志位 useSmart =true ,分词器使用智能切分策略, =false则使用细粒度切分
*
* @return useSmart
*/
public boolean useSmart() {
return useSmart;
} /**
* 设置useSmart标志位 useSmart =true ,分词器使用智能切分策略, =false则使用细粒度切分
*
* @param useSmart
*/
public void setUseSmart(boolean useSmart) {
this.useSmart = useSmart;
} /**
* 新加函数:设置主词典路径
*
* @return String 主词典路径
*/
public void setMainDictionary(String path) {
if(!StringUtils.isBlank(path)){
this.PATH_DIC_MAIN = path;
}
} /**
* 获取主词典路径
*
* @return String 主词典路径
*/
public String getMainDictionary() {
return PATH_DIC_MAIN;
} /**
* 获取量词词典路径
*
* @return String 量词词典路径
*/
public String getQuantifierDicionary() {
return PATH_DIC_QUANTIFIER;
} /**
* 获取扩展字典配置路径
*
* @return List<String> 相对类加载器的路径
*/
public List<String> getExtDictionarys() {
List<String> extDictFiles = new ArrayList<String>(2); String extDictCfg = props.getProperty(EXT_DICT);
if (extDictCfg != null) {
// 使用;分割多个扩展字典配置
String[] filePaths = extDictCfg.split(";");
if (filePaths != null) {
for (String filePath : filePaths) {
if (filePath != null && !"".equals(filePath.trim())) {
extDictFiles.add(filePath.trim());
}
}
}
}
return extDictFiles;
} /**
* 获取扩展停止词典配置路径
*
* @return List<String> 相对类加载器的路径
*/
public List<String> getExtStopWordDictionarys() {
List<String> extStopWordDictFiles = new ArrayList<String>(2);
String extStopWordDictCfg = props.getProperty(EXT_STOP);
if (extStopWordDictCfg != null) {
// 使用;分割多个扩展字典配置
String[] filePaths = extStopWordDictCfg.split(";");
if (filePaths != null) {
for (String filePath : filePaths) {
if (filePath != null && !"".equals(filePath.trim())) {
extStopWordDictFiles.add(filePath.trim());
}
}
}
}
return extStopWordDictFiles;
}
}

二、IKAnalyzer.cfg.xml默认不指定自定义词典

  原因有二:

  其一、我们是动态配置自定义词典,这里配不配配置又何妨

  其二、如果这里配置了自定义词典、后面使用我们指定的词典时 还需要清空这个里配置的词典、

  为什么要清空词典?这里我要说明一下为什么在使用我们自定义的某个词典前要清空词典:因为你不清空默认就是累加。在使用分词的时候,就是系统配置的词典(或前一次使用的词典)+你当前配置的某个词典的合集。

  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict"></entry> <!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">com/unruly/test/stopword.dic;</entry> </properties>

三、准备定义的词典:(我这准备了三个)

四、获取分词

1、配置我们自己的MyConfiguration ,动态指定词典路径

MyConfiguration mycfg = new MyConfiguration();
mycfg.setUseSmart(true); //true 用智能分词 ,false细粒度
mycfg.setMainDictionary("com/unruly/test/dict1.dic");//动态设置自定义的词典

词典也动态指定了,是不是现在就可以使用指定的词典分词了呢?天真。

2、手动去配置(刷新)词典的词组

我们仅仅指定了词典的文件是根本没有用的,虽然运行起来不会报错,但是仔细去看文本拆分出来的词组你会发现你这个配置根本没有起到作用。这时候我们就需要手动的去刷新Dictionary对象的words属性。

首先我们要拿到Dictionary对象(单例的)

private static Dictionary singleton;
if (singleton == null) {
singleton = Dictionary.initial(mycfg);
}

其次我们动过这个singleton 对象来设置words()

//dictList:通过我们指定的词典文件获取到的词组list
dictList = getWordList(dict);
singleton.addWords(dictList);

其实做到这一步就已经可以用于我们指定的词典分词了,但是我们似乎忘记了一件事情:清空不需要的词组,如:我们第一次使用了A词典分词。第二次要用B词典进行分词。这时候如果你不想用A里面的分词时我们就需要把A词典从singleton 对象中移除去。

//在使用新词典时,清除其他词典(刷新)
if(dictList.size()>0){
singleton.disableWords(dictList);
}

这样才是正在的OK了

3、开始分词

String content = "曾做过周朝“守藏室之官”(管理藏书的官员),是中国古代伟大的思想家、哲学家、文学家和史学家,"
+ "被道教尊为教祖,世界文化名人。老子思想主张“无为”,《老子》以“道”解释宇宙万物的演变,"
+ "“道”为客观自然规律,同时又具有“独立不改,周行而不殆”的永恒意义。《老子》书中包括大量"
+ "朴素辩证法观点,如以为一切事物均具有正反两面,并能由对立而转化,是为“反者道之动”,“正复为奇,"
+ "善复为妖”,“祸兮福之所倚,福兮祸之所伏”。又以为世间事物均为“有”与“无”之统一,“有、无相生”,"
+ "而“无”为基础,“天下万物生于有,有生于无”。他关于民众的格言有:“天之道,损有余而补不足,人之道"
+ "则不然,损不足以奉有余”;“民之饥,以其上食税之多”;“民之轻死,以其上求生之厚”;“民不畏死,奈何以"
+ "死惧之”。他的哲学思想和由他创立的道家学派,不但对中国古代思想文化的发展作出了重要贡献,而且对"
+ "中国2000多年来思想文化的发展产生了深远的影响。关于他的身份,还有人认为他是老莱子,也是楚国人,"
+ "跟孔子同时,曾著书十五篇宣传道家之用。";
StringReader input = new StringReader(content.trim()); IKSegmenter ikSeg = new IKSegmenter(input,mycfg);
Lexeme lexeme=null;
while((lexeme=ikSeg.next())!=null){
String keys = lexeme.getLexemeText();
if(keys.length()>1){
System.out.println(keys);
}
}
input.close();

五、分词结果:

1、使用jar包自带的词典:org/wltea/analyzer/dic/main2012.dic

2、使用dict1词典:

3、使用dict2词典:

4、使用dict3词典:

 六、总结解释:从结果可以看出,同样的一段文本,使用不同的词典,获取到的词组是不一样的并且获得的词组不会混杂

至于“2000” 、“十五篇” 这种带数字和字母的词组分词器会默认拆分出来的。至于为啥?你问我?我也不知道。因为我们搞的是中文分词器,程序给你把数字,单词也拆出来也是正常的

七、demo完整代码:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Properties; import javax.imageio.stream.FileImageInputStream; import org.apache.commons.lang.StringUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.util.ResourceLoader;
import org.wltea.analyzer.cfg.Configuration;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import org.wltea.analyzer.dic.Dictionary;
import org.wltea.analyzer.lucene.IKAnalyzer;
import org.wltea.analyzer.util.IKTokenizerFactory; public class TestIK {
private static Dictionary singleton;
private static ResourceLoader loader;
static List<String> dictList = new ArrayList<String>(); public static void main(String[] args) throws IOException {
for (int i = 0; i < 4; i++) {
test(i);
} } public static void test(int num) throws IOException{
String content = "曾做过周朝“守藏室之官”(管理藏书的官员),是中国古代伟大的思想家、哲学家、文学家和史学家,"
+ "被道教尊为教祖,世界文化名人。老子思想主张“无为”,《老子》以“道”解释宇宙万物的演变,"
+ "“道”为客观自然规律,同时又具有“独立不改,周行而不殆”的永恒意义。《老子》书中包括大量"
+ "朴素辩证法观点,如以为一切事物均具有正反两面,并能由对立而转化,是为“反者道之动”,“正复为奇,"
+ "善复为妖”,“祸兮福之所倚,福兮祸之所伏”。又以为世间事物均为“有”与“无”之统一,“有、无相生”,"
+ "而“无”为基础,“天下万物生于有,有生于无”。他关于民众的格言有:“天之道,损有余而补不足,人之道"
+ "则不然,损不足以奉有余”;“民之饥,以其上食税之多”;“民之轻死,以其上求生之厚”;“民不畏死,奈何以"
+ "死惧之”。他的哲学思想和由他创立的道家学派,不但对中国古代思想文化的发展作出了重要贡献,而且对"
+ "中国2000多年来思想文化的发展产生了深远的影响。关于他的身份,还有人认为他是老莱子,也是楚国人,"
+ "跟孔子同时,曾著书十五篇宣传道家之用。";
StringReader input = new StringReader(content.trim());
MyConfiguration mycfg = new MyConfiguration();
mycfg.setUseSmart(true); //true 用智能分词 ,false细粒度 if (singleton == null) {
singleton = Dictionary.initial(mycfg);
} String dict = null;
if(num==0){
dict = "org/wltea/analyzer/dic/main2012.dic";//分词jar包自带的词典
System.out.println("加载扩展词典:"+dict);
mycfg.setMainDictionary(dict);//动态设置自定义的词库 //在使用新词典时,清除其他词典(刷新)
if(dictList.size()>0){
singleton.disableWords(dictList);
} //dictList:通过我们指定的词典文件获取到的词组list
dictList = getWordList(dict);
singleton.addWords(dictList);
}else if(num==1){
dict = "com/unruly/test/dict1.dic";
System.out.println("加载扩展词典:"+dict);
mycfg.setMainDictionary(dict);//动态设置自定义的词库 //在使用新词典时,清除其他词典(刷新)
if(dictList.size()>0){
singleton.disableWords(dictList);
} dictList = getWordList(dict);
singleton.addWords(dictList);
}else if(num==2){
dict = "com/unruly/test/dict2.dic";
System.out.println("加载扩展词典:"+dict);
mycfg.setMainDictionary(dict);//动态设置自定义的词库 //在使用新词典时,清除其他词典(刷新)
if(dictList.size()>0){
singleton.disableWords(dictList);
} dictList = getWordList(dict);
singleton.addWords(dictList);
}else if(num==3){
dict = "com/unruly/test/dict3.dic";
System.out.println("加载扩展词典:"+dict);
mycfg.setMainDictionary(dict);//动态设置自定义的词库 //在使用新词典时,清除其他词典(刷新)
if(dictList.size()>0){
singleton.disableWords(dictList);
} dictList = getWordList(dict);
singleton.addWords(dictList);
} IKSegmenter ikSeg = new IKSegmenter(input,mycfg); Lexeme lexeme=null;
while((lexeme=ikSeg.next())!=null){
String keys = lexeme.getLexemeText(); if(keys.length()>1){
System.out.println(keys);
}
}
input.close();
} /**
* 读取字典
* @param dict
* @return
*/
public static List<String> getWordList(String dict) {
List<String> list = new ArrayList<>();
InputStream is = null;
try {
is = TestIK.class.getClass().getResourceAsStream("/"+dict);
BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"), 1024);
String theWord = null;
do {
theWord = br.readLine();
if (theWord != null && !"".equals(theWord.trim())) {
list.add(theWord);
}
} while (theWord != null);
} catch (IOException ioe) {
System.err.println("字典文件读取失败:"+dict);
ioe.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
is = null;
}
} catch (IOException e) {
e.printStackTrace();
}
} return list;
} }

IK-Analyzer(5.3.1)动态配置自定义词典的更多相关文章

  1. 在使用Hanlp配置自定义词典时遇到的问题

    要使用hanlp加载自定义词典可以通过修改配置文件hanlp.properties来实现.要注意的点是: 1. root根路径的配置: hanlp.properties中配置如下: #本配置文件中的路 ...

  2. Hanlp配置自定义词典遇到的问题与解决方法

    本文是整理了部分网友在配置hanlp自定义词典时遇到的一小部分问题,同时针对这些问题,也提供另一些解决的方案以及思路.这里分享给大家学习参考. 要使用hanlp加载自定义词典可以通过修改配置文件han ...

  3. Solr学习(2) Solr4.2.0+IK Analyzer 2012

    Solr学习(二) Solr4.2.0+IK Analyzer 2012 开场白: 本章简单讲述如何在solr中配置著名的 IK Analyzer 分词器. 本章建立在 Solr学习(一)  基础上进 ...

  4. solr添加中文IK分词器,以及配置自定义词库

    Solr是一个基于Lucene的Java搜索引擎服务器.Solr 提供了层面搜索.命中醒目显示并且支持多种输出格式(包括 XML/XSLT 和 JSON 格式).它易于安装和配置,而且附带了一个基于H ...

  5. ElasticSearch7.3学习(十五)----中文分词器(IK Analyzer)及自定义词库

    1. 中文分词器 1.1 默认分词器 先来看看ElasticSearch中默认的standard 分词器,对英文比较友好,但是对于中文来说就是按照字符拆分,不是那么友好. GET /_analyze ...

  6. 转:solr6.0配置中文分词器IK Analyzer

    solr6.0中进行中文分词器IK Analyzer的配置和solr低版本中最大不同点在于IK Analyzer中jar包的引用.一般的IK分词jar包都是不能用的,因为IK分词中传统的jar不支持s ...

  7. 我与solr(六)--solr6.0配置中文分词器IK Analyzer

    转自:http://blog.csdn.net/linzhiqiang0316/article/details/51554217,表示感谢. 由于前面没有设置分词器,以至于查询的结果出入比较大,并且无 ...

  8. 阿里云容器服务--配置自定义路由服务应对DDOS攻击

    阿里云容器服务--配置自定义路由服务应对DDOS攻击 摘要: 容器服务中,除了slb之外,自定义路由服务(基于HAProxy)也可以作为DDOS攻击的一道防线,本文阐述了几种方法来应对普通规模的DDO ...

  9. Lucene全文搜索之分词器:使用IK Analyzer中文分词器(修改IK Analyzer源码使其支持lucene5.5.x)

    注意:基于lucene5.5.x版本 一.简单介绍下IK Analyzer IK Analyzer是linliangyi2007的作品,再此表示感谢,他的博客地址:http://linliangyi2 ...

随机推荐

  1. dubbo 笔记-XML配置文件简介

    <dubbo:service/> 服务配置,用于暴露一个服务,定义服务的元信息,一个服务可以用多个协议暴露,一个服务也可以注册到多个注册中心. eg.<dubbo:service r ...

  2. sublime中安装package control总是失败

    今天下载了个sublime编辑器,要运行vue文件,想让vue也能高亮显示,在网上搜了一下如何安装.但总是提示控制器没有安装Package Control:There are no packages ...

  3. Java反射机制(Reflect)解析

    一.导读 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计 ...

  4. 【机器学习】支持向量机(SVM)

    感谢中国人民大学胡鹤老师,课程深入浅出,非常好 关于SVM 可以做线性分类.非线性分类.线性回归等,相比逻辑回归.线性回归.决策树等模型(非神经网络)功效最好 传统线性分类:选出两堆数据的质心,并做中 ...

  5. 在你的网站实现qq登陆(php)

    这个qq的oauth2.1有个坑,坑了我半天,后来查了不少资料总算弄通了,现在把详细步骤记录下来. 步骤一.登陆http://connect.qq.com/     步骤二.创建应用.我创建的是wen ...

  6. 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest H. Delete Them

    H. Delete Them time limit per test 2 seconds memory limit per test 512 megabytes input standard inpu ...

  7. Windows下caffe的配置和调用caffe库(二)

    二. Caffe库的调用: 新建空白项目,将配置管理器更改为x64运行方式.(release和Debug均可). Debug配置: 1)      包含目录: D:\caffe-master\incl ...

  8. HTML学习笔记 w3sCss盒子模型(阴影)(div的一些使用)案例 第十节 (原创) 参考使用表

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 数据结构--汉诺塔递归Java实现

    /*汉诺塔递归 * 1.将编号0-N-1个圆盘,从A塔座移动到B上面 * 2.将编号N的1个圆盘,从A移动到C上面 * 3.最后将B上面的N-1个圆盘移动到C上面 * 注意:盘子的编号从上到下1-N ...

  10. PHP--最常用--必背函数总结!php学习者收藏必备!

    一.PHP系统函数 函数 功能 用法 var_dump() 打印变量结构信息,包括类型和值.数组将递归展开值 var_dump ( $arg1...); echo():是语法结构 输出一个或者多个字符 ...