私は (単純な?) JFlex トークナイザーを作成しています。その目的は、文字列を取得し、中国語のチャンク (またはハンスクリプトを使用) とラテンスクリプトの部分を分解することです。トークナイザーはブランド名に適用されます。私の使用例では、ブランド名にラテン語と中国語の名前の両方が含まれる場合があります (例: "Lenovo 联想")。
ブランド名には、さらに数字 (7up)、ハイフン (Hewlett-Packard)、アンパサンド (P&G) などを含めることができます。中国語と非中国語の名前がスペースや区切りなしで一緒に書かれている場合を除いて、私のトークナイザーはほとんど機能します。具体的には、成功した解析と失敗した解析の例を次に示します。
"Calvin Klein卡尔文.克莱" - "Calvin Klein" と "卡尔文.克莱" に正常に分割され、期待されるスクリプト (ラテン語とハン語) を持つものとしてタグ付けされます。
"圣威廉SAINT WILLIAM" - "圣威廉SAINT" (Han chars としてマーク) と "WILLIAM" (Latin としてマーク) に誤って分割されます。
「史努力比SNOOPY」 - 誤って単一の漢トークンと見なされます。
私のルールはかなり明白だと思っていましたが、結果はそうではないことを示しているようです. これが私のルールセットです:
digit = [0-9]
whitespace = [ \t\r\n] | \r\n
latin = [\u0041-\u005a\u0061-\u007a\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u01bf\u01c4-\u024f]
han = [\u3400-\u9fff\uf900-\ufaff\u2f800-\u2fa1f]
// Punctuation in the middle or end of string sequences in a particular script
latin_middle = [&.\-'`‘]
latin_end = [.]
han_middle = [.]
// A basic Latin token contains a mixture of Latin characters and possibly digits.
basic_latin_tok = ({latin} | {digit})+
compound_latin_tok = {basic_latin_tok} (({whitespace}+ | {latin_middle}) {basic_latin_tok})*{latin_end}?
basic_han_tok = {han}({han} | {digit})*
| ({han} | {digit})*{han}
compound_han_tok = {basic_han_tok}({han_middle}{basic_han_tok})*
%%
{compound_latin_tok} { return "Latin"; }
{compound_han_tok} { return "Han"; }
. { /* skip everything else */ }
私は何を間違っていますか?
ありがとう!!
編集
SourceForge JFlex メーリング リストのメンバーに尋ねたところ、そのうちの 1 人から返信がありました。JFlex 1.4.* は、16 ビットで表現できない Unicode 文字を処理できないことがわかりました。上記で指定した漢字の文字範囲の一部は 16 ビット値を超えるため、JFlex は混乱します。それらを正規表現から削除すると、すべてうまく機能しました。
参考: http: //jflex.de/manual.html#SECTION000101000000000000000