Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息

Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息在此回复牛妞的关于程序中分词器的问题,其实可以直接很简单的在词库中配置就好了,Lucene中分词的所有信息我们都可以从TokenStream流中获取.分词器的核心类Analyzer,TokenStream,Tokenizer,TokenFilter.AnalyzerLucene中的分词器有Stand…

大家好,又见面了,我是你们的朋友全栈君。

Lucene学习-深入Lucene分词器,TokenStream获取分词详细信息

在此回复牛妞的关于程序中分词器的问题,其实可以直接很简单的在词库中配置就好了,Lucene中分词的所有信息我们都可以从TokenStream流中获取.

分词器的核心类Analyzer,TokenStream,Tokenizer,TokenFilter.

Analyzer

Lucene中的分词器有StandardAnalyzer,StopAnalyzer,SimpleAnalyzer,WhitespaceAnalyzer.

TokenStream

分词器做好处理之后得到的一个流,这个流中存储了分词的各种信息.可以通过TokenStream有效的获取到分词单元

Tokenizer

主要负责接收字符流Reader,将Reader进行分词操作.有如下一些实现类

KeywordTokenizer,

standardTokenizer,

CharTokenizer

|—-WhitespaceTokenizer

|—-LetterTokenizer

|—-LowerCaseTokenizer

TokenFilter

将分好词的语汇单元进行各种各样的过滤.

查看分词器的分词信息

 

package com.icreate.analyzer.luence;

import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.SimpleAnalyzer;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.util.Version;

/**
 *
 *  AnalyzerUtil.java   
 *
 *  @version : 1.1
 *  
 *  @author  : 苏若年    <a href="mailto:DennisIT@163.com">发送邮件</a>
 *    
 *  @since   : 1.0        创建时间:    2013-4-14  上午11:05:45
 *     
 *  TODO     : 
 *
 */
public class AnalyzerUtil {

    /**
     *
     * Description:         查看分词信息
     * @param str        待分词的字符串
     * @param analyzer    分词器
     *
     */
    public static void displayToken(String str,Analyzer analyzer){
        try {
            //将一个字符串创建成Token流
            TokenStream stream  = analyzer.tokenStream("", new StringReader(str));
            //保存相应词汇
            CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
            while(stream.incrementToken()){
                System.out.print("[" + cta + "]");
            }
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        Analyzer aly1 = new StandardAnalyzer(Version.LUCENE_36);
        Analyzer aly2 = new StopAnalyzer(Version.LUCENE_36);
        Analyzer aly3 = new SimpleAnalyzer(Version.LUCENE_36);
        Analyzer aly4 = new WhitespaceAnalyzer(Version.LUCENE_36);
        
        String str = "hello kim,I am dennisit,我是 中国人,my email is dennisit@163.com, and my QQ is 1325103287";
        
        AnalyzerUtil.displayToken(str, aly1);
        AnalyzerUtil.displayToken(str, aly2);
        AnalyzerUtil.displayToken(str, aly3);
        AnalyzerUtil.displayToken(str, aly4);
    }
}

 程序执行结果

 

 

[hello][kim][i][am][dennisit][我][是][中][国][人][my][email][dennisit][163][com][my][qq][1325103287]
[hello][kim][i][am][dennisit][我是][中国人][my][email][dennisit][com][my][qq]
[hello][kim][i][am][dennisit][我是][中国人][my][email][is][dennisit][com][and][my][qq][is]
[hello][kim,I][am][dennisit,我是][中国人,my][email][is][dennisit@163.com,][and][my][QQ][is][1325103287]

 

 

standardanalyzer将数字作为一个整体,每个单词都进行分隔

stopanalyzer将数字停用 中文不起作用,只坐空格分割

simpleanalyzer将数字停用 中文不起作用,只按照空格分割

whitespaceanalyzer按照空格分隔,中文不起作用

展示分词的详细信息

 

 

/**
     * 
     * Description:        显示分词的全部信息
     * @param str
     * @param analyzer
     *
     */
    public static void displayAllTokenInfo(String str, Analyzer analyzer){
        try {
            //第一个参数只是标识性没有实际作用
            TokenStream stream = analyzer.tokenStream("", new StringReader(str));
            //获取词与词之间的位置增量
            PositionIncrementAttribute postiona = stream.addAttribute(PositionIncrementAttribute.class);
            //获取各个单词之间的偏移量
            OffsetAttribute offseta = stream.addAttribute(OffsetAttribute.class);
            //获取每个单词信息
            CharTermAttribute chara = stream.addAttribute(CharTermAttribute.class);
            //获取当前分词的类型
            TypeAttribute typea = stream.addAttribute(TypeAttribute.class);
            while(stream.incrementToken()){
                System.out.print("位置增量" +postiona.getPositionIncrement()+":\t");
                System.out.println(chara+"\t[" + offseta.startOffset()+" - " + offseta.endOffset() + "]\t<" + typea +">");
            }
            System.out.println();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

 

 

测试代码

        Analyzer aly1 = new StandardAnalyzer(Version.LUCENE_36);
        Analyzer aly2 = new StopAnalyzer(Version.LUCENE_36);
        Analyzer aly3 = new SimpleAnalyzer(Version.LUCENE_36);
        Analyzer aly4 = new WhitespaceAnalyzer(Version.LUCENE_36);
        
        String str = "hello kim,I am dennisit,我是 中国人,my email is dennisit@163.com, and my QQ is 1325103287";
        
        AnalyzerUtil.displayAllTokenInfo(str, aly1);
        AnalyzerUtil.displayAllTokenInfo(str, aly2);
        AnalyzerUtil.displayAllTokenInfo(str, aly3);
        AnalyzerUtil.displayAllTokenInfo(str, aly4);

 程序运行结果

位置增量1:    hello    [0 - 5]    <type=<ALPHANUM>>
位置增量1:    kim    [6 - 9]    <type=<ALPHANUM>>
位置增量1:    i    [10 - 11]    <type=<ALPHANUM>>
位置增量1:    am    [12 - 14]    <type=<ALPHANUM>>
位置增量1:    dennisit    [15 - 23]    <type=<ALPHANUM>>
位置增量1:    我    [24 - 25]    <type=<IDEOGRAPHIC>>
位置增量1:    是    [25 - 26]    <type=<IDEOGRAPHIC>>
位置增量1:    中    [27 - 28]    <type=<IDEOGRAPHIC>>
位置增量1:    国    [28 - 29]    <type=<IDEOGRAPHIC>>
位置增量1:    人    [29 - 30]    <type=<IDEOGRAPHIC>>
位置增量1:    my    [31 - 33]    <type=<ALPHANUM>>
位置增量1:    email    [34 - 39]    <type=<ALPHANUM>>
位置增量2:    dennisit    [43 - 51]    <type=<ALPHANUM>>
位置增量1:    163    [52 - 55]    <type=<NUM>>
位置增量1:    com    [56 - 59]    <type=<ALPHANUM>>
位置增量2:    my    [65 - 67]    <type=<ALPHANUM>>
位置增量1:    qq    [68 - 70]    <type=<ALPHANUM>>
位置增量2:    1325103287    [74 - 84]    <type=<NUM>>

位置增量1:    hello    [0 - 5]    <type=word>
位置增量1:    kim    [6 - 9]    <type=word>
位置增量1:    i    [10 - 11]    <type=word>
位置增量1:    am    [12 - 14]    <type=word>
位置增量1:    dennisit    [15 - 23]    <type=word>
位置增量1:    我是    [24 - 26]    <type=word>
位置增量1:    中国人    [27 - 30]    <type=word>
位置增量1:    my    [31 - 33]    <type=word>
位置增量1:    email    [34 - 39]    <type=word>
位置增量2:    dennisit    [43 - 51]    <type=word>
位置增量1:    com    [56 - 59]    <type=word>
位置增量2:    my    [65 - 67]    <type=word>
位置增量1:    qq    [68 - 70]    <type=word>

位置增量1:    hello    [0 - 5]    <type=word>
位置增量1:    kim    [6 - 9]    <type=word>
位置增量1:    i    [10 - 11]    <type=word>
位置增量1:    am    [12 - 14]    <type=word>
位置增量1:    dennisit    [15 - 23]    <type=word>
位置增量1:    我是    [24 - 26]    <type=word>
位置增量1:    中国人    [27 - 30]    <type=word>
位置增量1:    my    [31 - 33]    <type=word>
位置增量1:    email    [34 - 39]    <type=word>
位置增量1:    is    [40 - 42]    <type=word>
位置增量1:    dennisit    [43 - 51]    <type=word>
位置增量1:    com    [56 - 59]    <type=word>
位置增量1:    and    [61 - 64]    <type=word>
位置增量1:    my    [65 - 67]    <type=word>
位置增量1:    qq    [68 - 70]    <type=word>
位置增量1:    is    [71 - 73]    <type=word>

位置增量1:    hello    [0 - 5]    <type=word>
位置增量1:    kim,I    [6 - 11]    <type=word>
位置增量1:    am    [12 - 14]    <type=word>
位置增量1:    dennisit,我是    [15 - 26]    <type=word>
位置增量1:    中国人,my    [27 - 33]    <type=word>
位置增量1:    email    [34 - 39]    <type=word>
位置增量1:    is    [40 - 42]    <type=word>
位置增量1:    dennisit@163.com,    [43 - 60]    <type=word>
位置增量1:    and    [61 - 64]    <type=word>
位置增量1:    my    [65 - 67]    <type=word>
位置增量1:    QQ    [68 - 70]    <type=word>
位置增量1:    is    [71 - 73]    <type=word>
位置增量1:    1325103287    [74 - 84]    <type=word>

 

自定义stop分词器

继承Analyzer复写public TokenStream tokenStream(String filename,Reader reader)方法

package org.dennisit.lucene.util;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.Set;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.LetterTokenizer;
import org.apache.lucene.analysis.LowerCaseFilter;
import org.apache.lucene.analysis.StopAnalyzer;
import org.apache.lucene.analysis.StopFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.util.Version;

/**
 *
 *  org.dennisit.lucene.utilMyStopAnalyzer.java   
 *
 *  @version : 1.1
 *  
 *  @author  : 苏若年         <a href="mailto:DennisIT@163.com">发送邮件</a>
 *    
 *  @since   : 1.0      创建时间:    2013-4-14  下午12:06:08
 *     
 *  TODO     : 
 *
 */
public class MyStopAnalyzer extends Analyzer{
    
    private Set stops;
    
    /**
     * 在原来停用词基础上增加自己的停用词
     * @param stopwords    自定义停用词采用数组传递
     */
    public MyStopAnalyzer(String[] stopwords){
        //会自动将字符串数组转换为Set
        stops = StopFilter.makeStopSet(Version.LUCENE_36,stopwords,true);
        //将原有的停用词加入到现在的停用词
        stops.addAll(StopAnalyzer.ENGLISH_STOP_WORDS_SET);
    }
    
    /**
     * 不传入参数表示使用原来默认的停用词
     */
    public MyStopAnalyzer(){
        //获取原有的停用词
        stops = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
    }
    
    @Override
    public TokenStream tokenStream(String filename,Reader reader){
        //为自定义分词器设定过滤链和Tokenizer
        return  new StopFilter(Version.LUCENE_36, 
                new LowerCaseFilter(Version.LUCENE_36, 
                new LetterTokenizer(Version.LUCENE_36,reader)),
                stops);
    }
    
    
    /**
     *
     * Description:         查看分词信息
     * @param str        待分词的字符串
     * @param analyzer    分词器
     *
     */
    public static void displayToken(String str,Analyzer analyzer){
        try {
            //将一个字符串创建成Token流
            TokenStream stream  = analyzer.tokenStream("", new StringReader(str));
            //保存相应词汇
            CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
            while(stream.incrementToken()){
                System.out.print("[" + cta + "]");
            }
            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        //获取原来的停用词
        Analyzer myAnalyzer1 = new MyStopAnalyzer();
        //追加自己的停用词
        Analyzer myAnalyzer2 = new MyStopAnalyzer(new String[]{"hate","fuck"});
        //分词处理的句子
        String text = "fuck! I hate you very much";
        
        displayToken(text, myAnalyzer1);
        displayToken(text, myAnalyzer2);
    }
}

 

程序运行结果

[fuck][i][hate][you][very][much]
[i][you][very][much]

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/163099.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 博客园博客背景图片设置

    博客园博客背景图片设置首先在博客园后台管理页面的相册上传自己想要设置背景的图片:上传完成之后点击该图片进去:看到大图再通过控制台获取路径然后转到设置:加上如下代码:最后效果:

    2022年7月4日
    20
  • 软件测试必问必背面试题

    软件测试必问必背面试题软件测试必问必背面试题01软件测试理论部分1.1测试概念1.请你分别介绍一下单元测试、集成测试、系统测试、验收测试、回归测试单元测试:完成最小的软件设计单元(模块)的验证工作,目标是确保模块被正确的编码集成测试:通过测试发现与模块接口有关的问题系统测试:是基于系统整体需求说明书的黑盒类测试,应覆盖系统所有联合的部件回归测试:回归测试是指在发生修改之后重新测试先前的测试用例以保证修改的正确性验收测试:这时相关的用户或独立测试人员根据测试计划和结果对系统进行测试和接收。验收测试包括Al

    2022年6月24日
    23
  • 【参赛作品29】基于openGauss数据库设计人力资源管理系统实验「建议收藏」

    【参赛作品29】基于openGauss数据库设计人力资源管理系统实验「建议收藏」本文作者:瓜西西本文主要面向openGauss数据库初学者,帮助初学者完成一些简单的数据库管理以及GUI,设计一个简单的人力资源管理系统。本文只包含部分代码,读者需要结合自己的数据库弹性公网、数据库用户及其密码等自身信息做出相应的修改。一、实验环境使用程序:putty.exe;IntelliJIDEA2021.1.1;apache-tomcat-9.0.46服务器名称:ecs-d8b3弹性公网:121.36.79.196端口号:26000表空间名:human_resource_

    2022年5月24日
    37
  • orange软件使用[通俗易懂]

    orange做数据分析契机实验手册目录orange软件部分界面展示小试牛刀:数据导入和展示小试牛刀:散点图绘制总结契机今天在上大数据时代实验课,作为一名软件工程专业的大三学生,在上这节公选课之前就决定这节课做完这个学期所有的实验报告,可以说“有亿点”不屑;尤其当老师说Python很麻烦的时候,我更是震惊了,因为我接触过这么多编程语言,Python真的很友好了,很傻瓜,但是当老师打开实验手册的时候,我真香了!!!下面先来看看手册的目录:实验手册目录为什么会真香呢,因为目录里这些有好多机器学习算法!

    2022年4月4日
    678
  • C语言开发简单的学生成绩管理系统(附源码)

    C语言开发简单的学生成绩管理系统(附源码)学生成绩管理系统开发语言:C语言开发工具:VisualStudio2019开发时间:2019.4.14开发者:summer@一、系统使用展示@二、系统功能@三、菜单@四、录入学生信息@五、打印学生信息@六、保存学生信息@七、读取学生信息@八、统计所有学生人数@九、查找学生信息@十、修改学生信息@十一、删除学生信息@十二、退出系统@十三、出错一、系统使用展示…

    2022年6月20日
    30
  • thread count_ThreadPool

    thread count_ThreadPoolThreadPool类提供一个线程池,该线程池可用于发送工作项、处理异步I/O、代表其他线程等待以及处理计时器。许多应用程序创建的线程都要在休眠状态中消耗大量时间,以等待事件发生。其他线程可能进入休眠状态,只被定期唤醒以轮询更改或更新状态信息。线程池通过为应用程序提供一个由系统管理的辅助线程池使您可以更为有效地使用线程。一个线程监视排到线程池的若干个等待操作的状态。当一个等待操作

    2022年9月24日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号