Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

释放双眼,带上耳机,听听看~!

原文:Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

1.2、分词的过程

**** 

1.2.1、分词器工作的过程

内置的分词器效果都不好,那怎么办?只能自己写了!在写之前当然是要先看看内置的分词器是怎么实现的了。从1.1分析分词效果,可以看出KeywordAnalyzer这个分词器最懒惰,基本什么事情也没做。并不是它不会做,而是我们没找到使用它的方法,就像手上拿着个盒子,不知道里面是什么,就不知道这个是干嘛的,有什么用。打开盒子,那就是要查看源代码了!

 

 

代码 1.2.1.1

 

Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Code

 1Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
using
 System;

 2
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 3
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
namespace
 Lucene.Net.Analysis

 4
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 5
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    

 6
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
/**/
///
 

<summary>
 "Tokenizes" the entire stream as a single token. This is useful

 7
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 for data like zip codes, ids, and some product names.

 8
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

</summary>

 9Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
    
public
 
class
 KeywordAnalyzer : Analyzer

10
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

11
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 
override
 TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader)

12
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

13
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 
new
 KeywordTokenizer(reader);

14
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

15
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

16
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 
override
 TokenStream ReusableTokenStream(System.String fieldName, System.IO.TextReader reader)

17
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

18
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            Tokenizer tokenizer 

 (Tokenizer)GetPreviousTokenStream();

19
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
if
 (tokenizer 

 
null
)

20
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

21
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                tokenizer 

 
new
 KeywordTokenizer(reader);

22
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                SetPreviousTokenStream(tokenizer);

23
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            }

24
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
else

25
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                tokenizer.Reset(reader);

26
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 tokenizer;

27
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

28
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    }

29
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)}

 

代码1.2.1.1 就是传说中的源码了。先看看注释,意思大体是“‘Tokenizes’整体的流变成一个个词。这个特别适用于邮编,ID,和商品名称。”Tokenizes应该是拆分的意思,字典上查不到这个词。

这段代码比较简单,只有两个方法,而第二个方法就是我们先前分析结果的时候用的(见段落1.1)。关键点就在于调用了KeywordTokenizer类。切到KeywordTokenizer类查看一下。

 

 

代码1.2.1.2

 

Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Code

 1Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
using
 System;

 2
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 3
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
namespace
 Lucene.Net.Analysis

 4
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 5
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    

 6
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
/**/
///
 

<summary>
 Emits the entire input as a single token.
</summary>

 7Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
    
public
 
class
 KeywordTokenizer : Tokenizer

 8
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 9
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

10
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
private
 
const
 
int
 DEFAULT_BUFFER_SIZE 

 
256
;

11
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

12
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
private
 
bool
 done;

13
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

14
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 KeywordTokenizer(System.IO.TextReader input) : 
this
(input, DEFAULT_BUFFER_SIZE)

15
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

16
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

17
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

18
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 KeywordTokenizer(System.IO.TextReader input, 
int
 bufferSize) : 
base
(input)

19
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

20
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
this
.done 

 
false
;

21
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

22
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

23
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 
override
 Token Next(Token result)

24
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

25
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
if
 (
!
done)

26
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

27
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                done 

 
true
;

28
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
int
 upto 

 
0
;

29
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                result.Clear();

30
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
char
[] buffer 

 result.TermBuffer();

31
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
while
 (
true
)

32
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

33
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
int
 length 

 input.Read(buffer, upto, buffer.Length 

 upto);

34
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
if
 (length 
<=
 
0
)

35
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        
break
;

36
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    upto 
+=
 length;

37
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
if
 (upto 

 buffer.Length)

38
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        buffer 

 result.ResizeTermBuffer(
1
 
+
 buffer.Length);

39
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                }

40
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                result.termLength 

 upto;

41
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
return
 result;

42
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            }

43
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 
null
;

44
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

45
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

46
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 
override
 
void
 Reset(System.IO.TextReader input)

47
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

48
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
base
.Reset(input);

49
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
this
.done 

 
false
;

50
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

51
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    }

52
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)}

 

代码 1.2.1.2 就是KeywordTokenizer的源码。代码量很小,却没有完成全部工作,而是将部分工作交给了父类。关注Lucene的人都可以知道,新版本中,分词这里换掉了,现在多了一个重载的Next方法。这里不讨论为什么要加这个重载,这篇文章主要是讲应用的。因为取词是用Next方法走的,那么只需要关注Next方法就可以了。KeywordTokenizer的父类是Tokenizer,但是在Tokenizer里找不到我们想要的关系,但是Tokenizer又继承自TokenStream。查看TokenStream类。

 

 

代码 1.2.1.3

 

Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Code

 1Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 2
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
using
 System;

 3
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 4
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
using
 Payload 

 Lucene.Net.Index.Payload;

 5
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 6
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
namespace
 Lucene.Net.Analysis

 7
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 8
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    

 9
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
/**/
///
 

<summary>
A TokenStream enumerates the sequence of tokens, either from

10
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 fields of a document or from query text.

11
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

<p>

12
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 This is an abstract class.  Concrete subclasses are:

13
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

<ul>

14
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

<li>
{@link Tokenizer}, a TokenStream

15
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 whose input is a Reader; and

16
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

<li>
{@link TokenFilter}, a TokenStream

17
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 whose input is another TokenStream.

18
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

</ul>

19
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 NOTE: subclasses must override at least one of {@link

20
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 #Next()} or {@link #Next(Token)}.

21
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

</summary>

22Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
    

23
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
public
 
abstract
 
class
 TokenStream

24
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

25
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

26
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Returns the next token in the stream, or null at EOS.

27
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 The returned Token is a "full private copy" (not

28
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 re-used across calls to next()) but will be slower

29
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 than calling {@link #Next(Token)} instead.. 

30
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</summary>

31Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
public
 
virtual
 Token Next()

32
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

33
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            Token result 

 Next(
new
 Token());

34
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            

35
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
if
 (result 
!=
 
null
)

36
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

37
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                Payload p 

 result.GetPayload();

38
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
if
 (p 
!=
 
null
)

39
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

40
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    result.SetPayload((Payload) p.Clone());

41
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                }

42
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            }

43
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            

44
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 result;

45
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

46
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

47
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Returns the next token in the stream, or null at EOS.

48
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 When possible, the input Token should be used as the

49
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 returned Token (this gives fastest tokenization

50
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 performance), but this is not required and a new Token

51
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 may be returned. Callers may re-use a single Token

52
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 instance for successive calls to this method.

53
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

<p>

54
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 This implicitly defines a "contract" between 

55
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 consumers (callers of this method) and 

56
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 producers (implementations of this method 

57
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 that are the source for tokens):

58
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

<ul>

59
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

<li>
A consumer must fully consume the previously 

60
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 returned Token before calling this method again.

</li>

61
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

<li>
A producer must call {@link Token\#Clear()}

62
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 before setting the fields in it & returning it

</li>

63
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</ul>

64
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 Note that a {@link TokenFilter} is considered a consumer.

65
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</summary>

66
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 
<param name="result">
a Token that may or may not be used to return

67
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</param>

68
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 
<returns>
 next token in the stream or null if end-of-stream was hit

69
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 
</returns>

70Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
public
 
virtual
 Token Next(Token result)

71
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

72
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 Next();

73
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

74
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

75
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Resets this stream to the beginning. This is an

76
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 optional operation, so subclasses may or may not

77
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 implement this method. Reset() is not needed for

78
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 the standard indexing process. However, if the Tokens 

79
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 of a TokenStream are intended to be consumed more than 

80
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 once, it is necessary to implement reset(). 

81
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</summary>

82Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
public
 
virtual
 
void
  Reset()

83
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

84
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

85
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

86
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Releases resources associated with this stream. 
</summary>

87Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
public
 
virtual
 
void
  Close()

88
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

89
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

90
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    }

91
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)}

 

代码 1.2.1.3 就是TokenStream类的源码。Next(Token)方法和Next()是相互调用的关系。但是因为Next(Token)方法在KeywordTokenizer里被重写掉了,因此,这里就可以忽略TokenStream的Next(Token)方法了。

 

从上面代码可以看出,调用Next()方法,实际上是传递给Next(Token)方法一个新Token实例。即使直接调用Next(Token),传递一个带有数据的Token,也会先被清除。在循环中,会把构造函数传入的流缓冲进Token类的缓冲区。ResizeTermBuffer方法是自动扩容用的,就像.Net Framework里的一些类能够自然扩容一样。比如List<T>,Hashtable或StringBuilder等。这个过程看不到分词的过程。不过这样就大致明白了分词器工作的流程。

 

1.2.2 如何让分词器分词

 

知道分词器如何工作了,但是现在还不明白分词如何分词。再回到1.1.2节,看到WhitespaceAnalyzer分词器似乎是学习的好选择。因为这个分词器只有遇到空格才会进行分词操作。

 

根据1.2.1的经验,直接查看WhitespaceTokenizer类。

 

 

代码1.2.2.1

 

Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Code

 1Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
using
 System;

 2
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 3
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
namespace
 Lucene.Net.Analysis

 4
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 5
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    

 6
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
/**/
///
 

<summary>
A WhitespaceTokenizer is a tokenizer that divides text at whitespace.

 7
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 Adjacent sequences of non-Whitespace characters form tokens. 

 8
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
///
 

</summary>

 9Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
    

10
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
public
 
class
 WhitespaceTokenizer : CharTokenizer

11
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

12
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Construct a new WhitespaceTokenizer. 
</summary>

13Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
public
 WhitespaceTokenizer(System.IO.TextReader in_Renamed) : 
base
(in_Renamed)

14
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

15
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

16
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

17
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Collects only characters which do not satisfy

18
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 {@link Character#isWhitespace(char)}.

19
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</summary>

20Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
protected
 
internal
 
override
 
bool
 IsTokenChar(
char
 c)

21
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

22
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 
!
System.Char.IsWhiteSpace(c);

23
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

24
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    }

25
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)}

 

很好,这段代码很短,可是没有看到我们想要的东西。继续看父类。

 

 

代码1.2.2.2

 

Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Code

 1Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
using
 System;

 2
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

 3
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
namespace
 Lucene.Net.Analysis

 4
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 5
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    

 6
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
/**/
///
 

<summary>
An abstract base class for simple, character-oriented tokenizers.
</summary>

 7Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
    
public
 
abstract
 
class
 CharTokenizer : Tokenizer

 8
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

 9
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 CharTokenizer(System.IO.TextReader input) : 
base
(input)

10
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

11
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

12
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

13
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
private
 
int
 offset 

 
0
, bufferIndex 

 
0
, dataLen 

 
0
;

14
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
private
 
const
 
int
 MAX_WORD_LEN 

 
255
;

15
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
private
 
const
 
int
 IO_BUFFER_SIZE 

 
1024
;

16
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
private
 
char
[] ioBuffer 

 
new
 
char
[IO_BUFFER_SIZE];

17
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

18
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Returns true iff a character should be included in a token.  This

19
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 tokenizer generates as tokens adjacent sequences of characters which

20
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 satisfy this predicate.  Characters for which this is false are used to

21
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 define token boundaries and are not included in tokens. 

22
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</summary>

23Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
protected
 
internal
 
abstract
 
bool
 IsTokenChar(
char
 c);

24
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        

25
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
/**/
///
 

<summary>
Called on each token character to normalize it before it is added to the

26
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 token.  The default implementation does nothing.  Subclasses may use this

27
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 to, e.g., lowercase tokens. 

28
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
///
 

</summary>

29Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
        
protected
 
internal
 
virtual
 
char
 Normalize(
char
 c)

30
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

31
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 c;

32
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

33
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

34
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 
override
 Token Next(Token token)

35
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

36
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            token.Clear();

37
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
int
 length 

 
0
;

38
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
int
 start 

 bufferIndex;

39
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
char
[] buffer 

 token.TermBuffer();

40
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
while
 (
true
)

41
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

42
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

43
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
if
 (bufferIndex 

=

 dataLen)

44
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

45
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    offset 
+=
 dataLen;

46
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    dataLen 

 input 
is
 Lucene.Net.Index.DocumentsWriter.ReusableStringReader 
?
 ((Lucene.Net.Index.DocumentsWriter.ReusableStringReader) input).Read(ioBuffer) : input.Read((System.Char[]) ioBuffer, 
0
, ioBuffer.Length);

47
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
if
 (dataLen 
<=
 
0
)

48
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

49
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        
if
 (length 

 
0
)

50
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                            
break
;

51
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        
else

52
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                            
return
 
null
;

53
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    }

54
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    bufferIndex 

 
0
;

55
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                }

56
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

57
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
char
 c 

 ioBuffer[bufferIndex
++
];

58
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

59
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
if
 (IsTokenChar(c))

60
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

61
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
//
 if it's a token char

62
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

63
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
if
 (length 

 
0
)

64
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        
//
 start of token

65
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
                        start 

 offset 
+
 bufferIndex 

 
1
;

66
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
else
 
if
 (length 

 buffer.Length)

67
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        buffer 

 token.ResizeTermBuffer(
1
 
+
 length);

68
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

69
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    buffer[length
++

 Normalize(c); 
//
 buffer it, normalized

70
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

71
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
if
 (length 

 MAX_WORD_LEN)

72
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                        
//
 buffer overflow!

73
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
                        
break
;

74
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                }

75
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                
else
 
if
 (length 

 
0
)

76
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)                    
//
 at non-Letter w/ chars

77
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
                    
break

//
 return 'em

78
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
            }

79
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

80
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            token.termLength 

 length;

81
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            token.startOffset 

 start;

82
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            token.endOffset 

 start 
+
 length;

83
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
return
 token;

84
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

85
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

86
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
public
 
override
 
void
 Reset(System.IO.TextReader input)

87
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)
{

88
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            
base
.Reset(input);

89
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            bufferIndex 

 
0
;

90
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            offset 

 
0
;

91
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)            dataLen 

 
0
;

92
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)        }

93
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)    }

94
Lucene.Net 2.3.1开发介绍 —— 二、分词(二)}

 

 

天公不作美,刚看到简单的,就来了个长的。无奈中。不过为什么要多一重继承呢?那就是有其他分词器也用到CharTokenizer了。而WhitespaceTokenizer中没有重写Next方法,而只是重写了IsTokenChar方法,几乎可以肯定。这个IsTokenChar才是重点。IsTokenChar故名思意,一看注释,果然!这个方法是判断是否遇到了分词的点的。这个其实和string类的Split方法相似。注意到Next方法关于IsTokenChar逻辑那一段,恩,果然是这样分词的。实际上就是拆分字符串嘛。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

安全运维

设计模式的设计原则

2021-12-12 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索