forked from apache/lucenenet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDefaultICUTokenizerConfig.cs
More file actions
148 lines (137 loc) · 7.17 KB
/
Copy pathDefaultICUTokenizerConfig.cs
File metadata and controls
148 lines (137 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// Lucene version compatibility level 8.6.1
using ICU4N.Globalization;
using ICU4N.Text;
using J2N;
using Lucene.Net.Analysis.Standard;
using System;
using System.IO;
namespace Lucene.Net.Analysis.Icu.Segmentation
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/// <summary>
/// Default <see cref="ICUTokenizerConfig"/> that is generally applicable
/// to many languages.
/// </summary>
/// <remarks>
/// Generally tokenizes Unicode text according to UAX#29
/// (<see cref="T:BreakIterator.GetWordInstance(ULocale.ROOT)"/>),
/// but with the following tailorings:
/// <list type="bullet">
/// <item><description>Thai, Lao, Myanmar, Khmer, and CJK text is broken into words with a dictionary.</description></item>
/// </list>
/// <para/>
/// @lucene.experimental
/// </remarks>
public class DefaultICUTokenizerConfig : ICUTokenizerConfig
{
/// <summary>Token type for words containing ideographic characters</summary>
public static readonly string WORD_IDEO = StandardTokenizer.TOKEN_TYPES[StandardTokenizer.IDEOGRAPHIC];
/// <summary>Token type for words containing Japanese hiragana</summary>
public static readonly string WORD_HIRAGANA = StandardTokenizer.TOKEN_TYPES[StandardTokenizer.HIRAGANA];
/// <summary>Token type for words containing Japanese katakana</summary>
public static readonly string WORD_KATAKANA = StandardTokenizer.TOKEN_TYPES[StandardTokenizer.KATAKANA];
/// <summary>Token type for words containing Korean hangul</summary>
public static readonly string WORD_HANGUL = StandardTokenizer.TOKEN_TYPES[StandardTokenizer.HANGUL];
/// <summary>Token type for words that contain letters</summary>
public static readonly string WORD_LETTER = StandardTokenizer.TOKEN_TYPES[StandardTokenizer.ALPHANUM];
/// <summary>Token type for words that appear to be numbers</summary>
public static readonly string WORD_NUMBER = StandardTokenizer.TOKEN_TYPES[StandardTokenizer.NUM];
/// <summary>Token type for words that appear to be emoji sequences</summary>
// ReSharper disable once ConvertToConstant.Global - matches the fields above to keep it static readonly
public static readonly string WORD_EMOJI = "<EMOJI>"; //StandardTokenizer.TOKEN_TYPES[StandardTokenizer.EMOJI]; // LUCENENET: 4.8.1 StandardTokenizer doesn't contain EMOJI
/// <summary>
/// the default breakiterators in use. these can be expensive to
/// instantiate, cheap to clone.
/// </summary>
// we keep the cjk breaking separate, that's because it cannot be customized (because dictionary
// is only triggered when kind = WORD, but kind = LINE by default and we have no non-evil way to change it)
private static readonly BreakIterator cjkBreakIterator = BreakIterator.GetWordInstance(UCultureInfo.InvariantCulture);
// TODO: if the wrong version of the ICU jar is used, loading these data files may give a strange error.
// maybe add an explicit check? http://icu-project.org/apiref/icu4j/com/ibm/icu/util/VersionInfo.html
// the same as ROOT, except no dictionary segmentation for cjk
private static readonly BreakIterator defaultBreakIterator =
ReadBreakIterator("Default.brk");
private static readonly BreakIterator myanmarSyllableIterator =
ReadBreakIterator("MyanmarSyllable.brk");
// TODO: deprecate this boolean? you only care if you are doing super-expert stuff...
private readonly bool cjkAsWords;
private readonly bool myanmarAsWords;
/// <summary>
/// Creates a new config. This object is lightweight, but the first
/// time the class is referenced, breakiterators will be initialized.
/// </summary>
/// <param name="cjkAsWords">true if cjk text should undergo dictionary-based segmentation,
/// otherwise text will be segmented according to UAX#29 defaults.</param>
/// <param name="myanmarAsWords">If this is true, all Han+Hiragana+Katakana words will be tagged as IDEOGRAPHIC.</param>
public DefaultICUTokenizerConfig(bool cjkAsWords, bool myanmarAsWords)
{
this.cjkAsWords = cjkAsWords;
this.myanmarAsWords = myanmarAsWords;
}
public override bool CombineCJ => cjkAsWords;
public override RuleBasedBreakIterator GetBreakIterator(int script)
{
switch (script)
{
case UScript.Japanese: return (RuleBasedBreakIterator)cjkBreakIterator.Clone();
case UScript.Myanmar:
if (myanmarAsWords)
{
return (RuleBasedBreakIterator)defaultBreakIterator.Clone();
}
else
{
return (RuleBasedBreakIterator)myanmarSyllableIterator.Clone();
}
default: return (RuleBasedBreakIterator)defaultBreakIterator.Clone();
}
}
public override string GetType(int script, int ruleStatus)
{
switch (ruleStatus)
{
case BreakIterator.WordIdeo:
return WORD_IDEO;
case BreakIterator.WordKana: //RuleBasedBreakIterator.WORD_KANA:
return script == UScript.Hiragana ? WORD_HIRAGANA : WORD_KATAKANA;
case BreakIterator.WordLetter: //RuleBasedBreakIterator.WORD_LETTER:
return script == UScript.Hangul ? WORD_HANGUL : WORD_LETTER;
case BreakIterator.WordNumber: //RuleBasedBreakIterator.WORD_NUMBER:
return WORD_NUMBER;
case EMOJI_SEQUENCE_STATUS:
return WORD_EMOJI;
default: /* some other custom code */
return "<OTHER>";
}
}
private static RuleBasedBreakIterator ReadBreakIterator(string filename)
{
using Stream @is = typeof(DefaultICUTokenizerConfig).FindAndGetManifestResourceStream(filename);
try
{
RuleBasedBreakIterator bi =
RuleBasedBreakIterator.GetInstanceFromCompiledRules(@is);
return bi;
}
catch (Exception e) when (e.IsIOException())
{
throw RuntimeException.Create(e);
}
}
}
}