中文分词源代码分析

因为NUTCH在中文分词方面的缺陷(只支持单字分词),很多朋友对搜索引擎中文分词很感兴趣。这里有一份我在最初接触分词技术的时候从网上获得的分词JAVA源代码,功能很齐全,并且自带词典,可以实际运行。虽然性能方面可能仍然有待商榷,但是满足初步的应用还是可以胜任的。如果只是为了对分词原理和编码进行了解和学习,那效果就更好了。Jar包可以从http://fanjingxin.googlepages.com/segmenter.jar下载,我先简单说一下使用方法。

 

 

下载以后无需解压缩可以直接运行,但是为了上传方便,源代码和class我都放了进去。所以你可以直接运行,想看源代码你就解压缩看。运行的时候需要命令参数,你先不给参数执行一下,它就会给你所需参数格式的提示。

 

 

执行语句例如:java -jar segmenter.jar -g test.txt  (其中-g代表文字格式,因为它支持简体,繁体,简繁体混合三种文本的分词;test.txt文本文件内容是你想要进行分词的文本,需要你自己创建一个,文件名字随便起。执行成功以后会在text.txt目录下新生成一个text.txt.seg文件,里面就是分词结果,可以用记事本查看。另外test.txt参数也可以是一个文件夹名字,文件夹里所有的文本文件内容都会被执行分词,分别生成一系列seg文件。

 

 

下面我们来看看源代码文件夹里的内容(大多是废话,见谅),其中segmenter.java是源代码,三个txt文件分别是三个词典,分别为简体中文的词典,繁体的和简繁混合的词典。其中多是有语义词汇。data文件夹里面也是一些词典,主要是一些无语义词的词典,包括8个词典,4个简体中文词典,4个繁体词典。里面主要是什么词大家自己打开看吧。

 

 

词典大家可以按照它里面的换行格式随意进行扩充,我们这里主要关注的是JAVA的源代码。这份代码唯一的毛病就是注释少的厉害,读起来稍微有点费时,因为我已经看过了,为了节省朋友们的时间少做无用功,我稍微做一下解析。

 

 

我们先来看看它的main函数,这样就可以搞清楚谁才是分词的主要函数。

public static void main(String[] argv) {

       Vector inputfiles = new Vector() ;//初始化一个文件容器,装载你要分词的文件

       String encoding = "BIG5";//默认文字编码格式

       int charform = segmenter.TRAD;//默认为简繁混合

       boolean debug = false;//这是作者编码的时候为了调试加的变量

       int i, j;

 

 

       for (i = 0; i < argv.length; i++) {

           if (argv[i].equals("-b")) {

              if (debug) System.out.println("Setting to Big5, TRAD");

              encoding = "BIG5";

              charform = segmenter.TRAD;

           } else if (argv[i].equals("-g")) {

              if (debug) System.out.println("Setting to GB, SIMP");

              encoding = "GBK";

              charform = segmenter.SIMP;

           } else if (argv[i].equals("-8")) {

              encoding = "UTF8";

              charform = segmenter.BOTH;

           } else if (argv[i].equals("-s")) {

              if (debug) System.out.println("Setting to SIMP");

              charform = segmenter.SIMP;

           } else if (argv[i].equals("-t")) {

              if (debug) System.out.println("Setting to TRAD");

              charform = segmenter.TRAD;

           } else if (argv[i].equals("-h")) {

              printHelp();

           } else {

              inputfiles.add(argv[i]);

           }

       }

//以上部分全部在读取命令行参数,并且将参数合适记录

 

 

       if (inputfiles.size() == 0) {

           System.out.println("ERROR: Please specify name of Chinese text file to segment./n");

           printHelp();

       }

//上面表示文件不存在

 

 

       System.err.println("Loading segmenter word list.  One moment please.");

       segmenter mainsegmenter = new segmenter(charform, true);

       System.err.println("Total keys " + mainsegmenter.zhwords.size());

 

 

       File tmpfile;

       String dirfiles[];

       for (i = 0; i < inputfiles.size(); i++) {

           tmpfile = new File((String)inputfiles.get(i));

           if (tmpfile.exists() == false) {

              System.out.println("ERROR: Source file " + (String)inputfiles.get(i) +

                               " does not exist./n");

              continue;

           }

           if (tmpfile.isDirectory() == true) {

              dirfiles = tmpfile.list();

              if (dirfiles != null) {

                  for (j = 0; j < dirfiles.length; j++) {

                     inputfiles.add((String)inputfiles.get(i) + File.separator +

                                   dirfiles[j]);

                  }

              }

              continue;

           }

              //以上代码,表示你的文件参数如果是文件夹,它需要遍历里面的所有文本文件

 

 

           System.err.println("Segmenting " + inputfiles.get(i) +

                            " with encoding " + encoding);

           mainsegmenter.segmentFile((String)inputfiles.get(i), encoding);

              //一句代码,分词搞定。说明segmentFile是分词实现的函数。

       }

    }

今天先就这样吧,有时间我再给大家稍微说说主要的segmentFile函数。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值