LUCENE3.0 自学吧 7 CharTokenizer

CharTokenizer 是一个抽象类,它主要是对西文字符进行分词处理的。常见的英文中,是以空格、标点为分隔符号的,在分词的时候,就是以这些分隔符作为分词的间隔符的。

 

[java]  view plain copy
 
  1. package org.apache.lucene.analysis;  
  2.    
  3. import java.io.IOException;  
  4. import java.io.Reader;  
  5.    
  6. import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;  
  7. import org.apache.lucene.analysis.tokenattributes.TermAttribute;  
  8. import org.apache.lucene.util.AttributeSource;  
  9.    
  10. //CharTokenizer是一个抽象类,貌似只有  
  11. // CharTokenizer token5 = new LetterTokenizer(input); 去实例化?  
  12. public abstract class CharTokenizer extends Tokenizer {  
  13.   public CharTokenizer(Reader input) {  
  14.     super(input);  
  15.     offsetAtt = addAttribute(OffsetAttribute.class);  
  16.     termAtt = addAttribute(TermAttribute.class);  
  17.   }  
  18.    
  19.   public CharTokenizer(AttributeSource source, Reader input) {  
  20.     super(source, input);  
  21.     offsetAtt = addAttribute(OffsetAttribute.class);  
  22.     termAtt = addAttribute(TermAttribute.class);  
  23.   }  
  24.    
  25.   public CharTokenizer(AttributeFactory factory, Reader input) {  
  26.     super(factory, input);  
  27.     offsetAtt = addAttribute(OffsetAttribute.class);  
  28.     termAtt = addAttribute(TermAttribute.class);  
  29.   }  
  30.    
  31.   private int offset = 0, bufferIndex = 0, dataLen = 0;  
  32.   private static final int MAX_WORD_LEN = 255;  
  33.   private static final int IO_BUFFER_SIZE = 4096;  
  34.   private final char[] ioBuffer = new char[IO_BUFFER_SIZE];  
  35.    
  36.   private TermAttribute termAtt;  
  37.   private OffsetAttribute offsetAtt;  
  38.    
  39.   protected abstract boolean isTokenChar(char c);  
  40. // 对字符进行处理,可以在CharTokenizer 的子类中实现  
  41.   protected char normalize(char c) {  
  42.     return c;  
  43.   }  
  44.    
  45.   @Override  
  46.   public final boolean incrementToken() throws IOException {  
  47.     clearAttributes();  
  48.     int length = 0;  
  49.     int start = bufferIndex;  
  50.     char[] buffer = termAtt.termBuffer();  
  51.     while (true) {  
  52.    
  53.       if (bufferIndex >= dataLen) {  
  54.         offset += dataLen;  
  55.         dataLen = input.read(ioBuffer);  
  56.         if (dataLen == -1) {  
  57.           dataLen = 0;                            // so next offset += dataLen won't decrement offset  
  58.           if (length > 0)  
  59.             break;  
  60.           else  
  61.             return false;  
  62.         }  
  63.         bufferIndex = 0;  
  64.       }  
  65.    
  66.       final char c = ioBuffer[bufferIndex++];  
  67.    
  68.       if (isTokenChar(c)) {               // if it's a token char  
  69.    
  70.         if (length == 0)                 // start of token  
  71.           start = offset + bufferIndex - 1;  
  72.         else if (length == buffer.length)  
  73.           buffer = termAtt.resizeTermBuffer(1+length);  
  74.    
  75.         buffer[length++] = normalize(c); // buffer it, normalized  
  76.    
  77.         if (length == MAX_WORD_LEN)      // buffer overflow!  
  78.           break;  
  79.    
  80.       } else if (length > 0)             // at non-Letter w/ chars  
  81.         break;                           // return 'em  
  82.     }  
  83.    
  84.     termAtt.setTermLength(length);  
  85.     offsetAtt.setOffset(correctOffset(start), correctOffset(start+length));  
  86.     return true;  
  87.   }  
  88.    
  89.   @Override  
  90.   public final void end() {  
  91.     // set final offset  
  92.     int finalOffset = correctOffset(offset);  
  93.     offsetAtt.setOffset(finalOffset, finalOffset);  
  94.   }  
  95.    
  96.   @Override  
  97.   public void reset(Reader input) throws IOException {  
  98.     super.reset(input);  
  99.     bufferIndex = 0;  
  100.     offset = 0;  
  101.     dataLen = 0;  
  102.   }  
  103. }  

实现 CharTokenizer 的具体类有 1 个,分别为: LetterTokenizer( 仅在核心包 ) 、

 

看看 LetterTokenizer 类:

 

[java]  view plain copy
 
  1. package org.apache.lucene.analysis;  
  2.    
  3. import java.io.Reader;  
  4.    
  5. // 只要读取到非字符的符号,就分词  
  6.    
  7. public class LetterTokenizer extends CharTokenizer {  
  8.    
  9. public LetterTokenizer(Reader in) {  
  10.     super(in);  
  11. }  
  12.    
  13.    
  14. protected boolean isTokenChar(char c) {  
  15.     return Character.isLetter(c);  
  16. }  
  17. }  
  18.    

做个测试就可以看到:

 

[java]  view plain copy
 
  1. package com.fpi.lucene.studying.test;  
  2.    
  3. import java.io.IOException;  
  4. import java.io.Reader;  
  5. import java.io.StringReader;  
  6.    
  7. import org.apache.lucene.analysis.CharTokenizer;  
  8. import org.apache.lucene.analysis.LetterTokenizer;  
  9. import org.apache.lucene.analysis.Tokenizer;  
  10. import org.apache.lucene.analysis.cjk.CJKTokenizer;  
  11. import org.apache.lucene.analysis.cn.ChineseTokenizer;  
  12.    
  13. public class JustTest {  
  14.        public static void main(String[] args) {  
  15.          Reader read = new StringReader("what are you doing,man?It's none of your business!");  
  16.        LetterTokenizer token5 = new LetterTokenizer(read);  
  17.        try {  
  18.                      while(token5.incrementToken()){  
  19.                              System.out.println(token5.toString());  
  20.                       }  
  21.               } catch (IOException e) {  
  22.                      // TODO Auto-generated catch block  
  23.                      e.printStackTrace();  
  24.               }  
  25.        }  
  26. }  

运行结果如下:

(startOffset=0,endOffset=4,term=what)

(startOffset=5,endOffset=8,term=are)

(startOffset=9,endOffset=12,term=you)

(startOffset=13,endOffset=18,term=doing)

(startOffset=19,endOffset=22,term=man)

(startOffset=23,endOffset=25,term=It)

(startOffset=26,endOffset=27,term=s)

(startOffset=28,endOffset=32,term=none)

(startOffset=33,endOffset=35,term=of)

(startOffset=36,endOffset=40,term=your)

(startOffset=41,endOffset=49,term=business)     

 

看到了吗?不但逗号和问号被分开,而且连 It’s 这个也被分解为 It 和 s 了。

 

没有非字符的英文字母串就可以作为一个词条,一个词条长度的限制为 255 个字符,可以在 CharTokenizer 抽象类中看到定义:

 

private static final int MAX_WORD_LEN = 255

 

猜你喜欢

转载自yzyzero.iteye.com/blog/2065537
今日推荐