热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java单例字典动态_IKAnalyzer(5.3.1)动态配置自定义词典

参考文献:http:blog.csdn.netfatpandaarticledetails37911079jar包:IK-Analyzer-extra-

参考文献: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

importjava.io.IOException;importjava.io.InputStream;importjava.util.ArrayList;importjava.util.InvalidPropertiesFormatException;importjava.util.List;importjava.util.Properties;importorg.apache.commons.lang.StringUtils;importorg.wltea.analyzer.cfg.Configuration;public class MyConfiguration implementsConfiguration {//懒汉单例

private static final Configuration CFG = newMyConfiguration();/** 分词器默认字典路径*/

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";privateProperties props;/** 是否使用smart方式分词*/

private booleanuseSmart;/*** 返回单例

*

*@returnConfiguration单例*/

public staticConfiguration getInstance() {returnCFG;

}/** 初始化配置文件*/MyConfiguration() {

props= newProperties();

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则使用细粒度切分

*

*@returnuseSmart*/

public booleanuseSmart() {returnuseSmart;

}/*** 设置useSmart标志位 useSmart =true ,分词器使用智能切分策略, =false则使用细粒度切分

*

*@paramuseSmart*/

public void setUseSmart(booleanuseSmart) {this.useSmart =useSmart;

}/*** 新加函数:设置主词典路径

*

*@returnString 主词典路径*/

public voidsetMainDictionary(String path) {if(!StringUtils.isBlank(path)){this.PATH_DIC_MAIN =path;

}

}/*** 获取主词典路径

*

*@returnString 主词典路径*/

publicString getMainDictionary() {returnPATH_DIC_MAIN;

}/*** 获取量词词典路径

*

*@returnString 量词词典路径*/

publicString getQuantifierDicionary() {returnPATH_DIC_QUANTIFIER;

}/*** 获取扩展字典配置路径

*

*@returnList 相对类加载器的路径*/

public ListgetExtDictionarys() {

List extDictFiles = new ArrayList(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());

}

}

}

}returnextDictFiles;

}/*** 获取扩展停止词典配置路径

*

*@returnList 相对类加载器的路径*/

public ListgetExtStopWordDictionarys() {

List extStopWordDictFiles = new ArrayList(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());

}

}

}

}returnextStopWordDictFiles;

}

}

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

原因有二:

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

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

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

IK Analyzer 扩展配置

com/unruly/test/stopword.dic;

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

93a24e3f55030465279aafe3e228f05f.png

4cf020b2e64187e93617530eb5967887.png

dbb0bb5f2021a63cb9f0f20e0da0baac.png

四、获取分词

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

MyConfiguration mycfg = newMyConfiguration();

mycfg.setUseSmart(true); //true 用智能分词 ,false细粒度

mycfg.setMainDictionary("com/unruly/test/dict1.dic");//动态设置自定义的词典

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

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

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

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

private staticDictionary 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= newStringReader(content.trim());

IKSegmenter ikSeg= newIKSegmenter(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

f9652fa7870f924f2bab492836f2f9ef.png

2、使用dict1词典:

aacb057446b40b7ad85a265fa2c22973.png

3、使用dict2词典:

7dd2d26e20a83e701f8f0b8600ff7535.png

4、使用dict3词典:

41cc04a80498ca204ae5758769c7f01e.png

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

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

七、demo完整代码:

importjava.io.BufferedReader;importjava.io.File;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.StringReader;importjava.util.ArrayList;importjava.util.Collections;importjava.util.HashMap;importjava.util.List;importjava.util.Properties;importjavax.imageio.stream.FileImageInputStream;importorg.apache.commons.lang.StringUtils;importorg.apache.lucene.analysis.Analyzer;importorg.apache.lucene.analysis.TokenStream;importorg.apache.lucene.analysis.tokenattributes.CharTermAttribute;importorg.apache.lucene.analysis.util.ResourceLoader;importorg.wltea.analyzer.cfg.Configuration;importorg.wltea.analyzer.core.IKSegmenter;importorg.wltea.analyzer.core.Lexeme;importorg.wltea.analyzer.dic.Dictionary;importorg.wltea.analyzer.lucene.IKAnalyzer;importorg.wltea.analyzer.util.IKTokenizerFactory;public classTestIK {private staticDictionary singleton;private staticResourceLoader loader;static List dictList &#61; new ArrayList();public static void main(String[] args) throwsIOException {for (int i &#61; 0; i <4; i&#43;&#43;) {

test(i);

}

}public static void test(int num) throwsIOException{

String content&#61; "曾做过周朝“守藏室之官”(管理藏书的官员)&#xff0c;是中国古代伟大的思想家、哲学家、文学家和史学家&#xff0c;"

&#43; "被道教尊为教祖&#xff0c;世界文化名人。老子思想主张“无为”&#xff0c;《老子》以“道”解释宇宙万物的演变&#xff0c;"

&#43; "“道”为客观自然规律&#xff0c;同时又具有“独立不改&#xff0c;周行而不殆”的永恒意义。《老子》书中包括大量"

&#43; "朴素辩证法观点&#xff0c;如以为一切事物均具有正反两面&#xff0c;并能由对立而转化&#xff0c;是为“反者道之动”&#xff0c;“正复为奇&#xff0c;"

&#43; "善复为妖”&#xff0c;“祸兮福之所倚&#xff0c;福兮祸之所伏”。又以为世间事物均为“有”与“无”之统一&#xff0c;“有、无相生”&#xff0c;"

&#43; "而“无”为基础&#xff0c;“天下万物生于有&#xff0c;有生于无”。他关于民众的格言有&#xff1a;“天之道&#xff0c;损有余而补不足&#xff0c;人之道"

&#43; "则不然&#xff0c;损不足以奉有余”&#xff1b;“民之饥&#xff0c;以其上食税之多”&#xff1b;“民之轻死&#xff0c;以其上求生之厚”&#xff1b;“民不畏死&#xff0c;奈何以"

&#43; "死惧之”。他的哲学思想和由他创立的道家学派&#xff0c;不但对中国古代思想文化的发展作出了重要贡献&#xff0c;而且对"

&#43; "中国2000多年来思想文化的发展产生了深远的影响。关于他的身份&#xff0c;还有人认为他是老莱子&#xff0c;也是楚国人&#xff0c;"

&#43; "跟孔子同时&#xff0c;曾著书十五篇宣传道家之用。";

StringReader input&#61; newStringReader(content.trim());

MyConfiguration mycfg&#61; newMyConfiguration();

mycfg.setUseSmart(true); //true 用智能分词 &#xff0c;false细粒度

if (singleton &#61;&#61; null) {

singleton&#61;Dictionary.initial(mycfg);

}

String dict&#61; null;if(num&#61;&#61;0){

dict&#61; "org/wltea/analyzer/dic/main2012.dic";//分词jar包自带的词典

System.out.println("加载扩展词典&#xff1a;"&#43;dict);

mycfg.setMainDictionary(dict);//动态设置自定义的词库//在使用新词典时&#xff0c;清除其他词典(刷新)

if(dictList.size()>0){

singleton.disableWords(dictList);

}//dictList:通过我们指定的词典文件获取到的词组list

dictList &#61;getWordList(dict);

singleton.addWords(dictList);

}else if(num&#61;&#61;1){

dict&#61; "com/unruly/test/dict1.dic";

System.out.println("加载扩展词典&#xff1a;"&#43;dict);

mycfg.setMainDictionary(dict);//动态设置自定义的词库//在使用新词典时&#xff0c;清除其他词典(刷新)

if(dictList.size()>0){

singleton.disableWords(dictList);

}

dictList&#61;getWordList(dict);

singleton.addWords(dictList);

}else if(num&#61;&#61;2){

dict&#61; "com/unruly/test/dict2.dic";

System.out.println("加载扩展词典&#xff1a;"&#43;dict);

mycfg.setMainDictionary(dict);//动态设置自定义的词库//在使用新词典时&#xff0c;清除其他词典(刷新)

if(dictList.size()>0){

singleton.disableWords(dictList);

}

dictList&#61;getWordList(dict);

singleton.addWords(dictList);

}else if(num&#61;&#61;3){

dict&#61; "com/unruly/test/dict3.dic";

System.out.println("加载扩展词典&#xff1a;"&#43;dict);

mycfg.setMainDictionary(dict);//动态设置自定义的词库//在使用新词典时&#xff0c;清除其他词典(刷新)

if(dictList.size()>0){

singleton.disableWords(dictList);

}

dictList&#61;getWordList(dict);

singleton.addWords(dictList);

}

IKSegmenter ikSeg&#61; newIKSegmenter(input,mycfg);

Lexeme lexeme&#61;null;while((lexeme&#61;ikSeg.next())!&#61;null){

String keys&#61;lexeme.getLexemeText();if(keys.length()>1){

System.out.println(keys);

}

}

input.close();

}/*** 读取字典

*&#64;paramdict

*&#64;return

*/

public static ListgetWordList(String dict) {

List list &#61; new ArrayList<>();

InputStream is&#61; null;try{

is&#61; TestIK.class.getClass().getResourceAsStream("/"&#43;dict);

BufferedReader br&#61; new BufferedReader(new InputStreamReader(is,"UTF-8"), 1024);

String theWord&#61; null;do{

theWord&#61;br.readLine();if (theWord !&#61; null && !"".equals(theWord.trim())) {

list.add(theWord);

}

}while (theWord !&#61; null);

}catch(IOException ioe) {

System.err.println("字典文件读取失败:"&#43;dict);

ioe.printStackTrace();

}finally{try{if (is !&#61; null) {

is.close();

is&#61; null;

}

}catch(IOException e) {

e.printStackTrace();

}

}returnlist;

}

}



推荐阅读
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
author-avatar
kikokikolove
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有