我正在编写一个(简单的?)JFlex标记生成器,其目标是取一个字符串,并将中文(或者更确切地说使用Han脚本)的块和拉丁文脚本中的部分分开。令牌化器应用于品牌名称,在我的用例中,品牌名称可以包含拉丁文和中文名称,例如“联想联想”。
品牌名称可以进一步包含数字(7up),连字符(Hewlett-Packard),&符号(P& G)等。我的标记器主要用于工作,除非中文和非中文名称一起写入任何空间或分隔。具体来说,这些是成功和不成功的解析的例子:
“Calvin Klein卡尔文。克莱” - 成功分裂为“Calvin Klein”和“卡尔文。克莱”,并将其标记为具有预期的剧本(拉丁文和汉文)
“圣威廉SAINT WILLIAM” - 错误地分为“圣威廉SAINT”(标记为Han chars)和“WILLIAM”(标记为拉丁语)。
“史努比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邮件列表上的人,其中一个回复给我 - 结果是JFlex 1.4。*无法处理16位无法表示的Unicode字符。由于我上面为Han字符指定的某些字符范围高于16位值,因此JFlex会感到困惑。从正则表达式中删除它们使它一切正常。
供参考:http://jflex.de/manual.html#SECTION000101000000000000000
答案 0 :(得分:1)
我问过SourceForge JFlex邮件列表上的人,其中一人回复了我 - 结果是JFlex 1.4。*无法处理16位无法表示的Unicode字符。
哦,但可以处理这些。
首先,让我对\ u2f800- \ u2fa1f进行更正。最后一个值确实无法在16位上表示,但仅仅因为UNICODE块定义在\ u2fa1d处停止,因此即使在其32位表示上,该值也是UNICODE无效
现在,说服JFlex处理好你的麻烦[\ u2f800- \ u2fa1d]范围的伎俩: Java代码(和字符串文字)使用排序的UTF16编码,因此16位“代理”(更高的UTF16字)后跟另外16位配对字符。
对于你需要的范围,你很幸运:第一个16位代理在整个范围内保持相同,即\ uD87E,而较低的16位在[\ uDC00- \ uDE1D]范围内变化。 所以,你的汉宏变成了
han = [\u3400-\u9fff\uf900-\ufaff] | \uD87E[\uDC00-\uDE1D]
我懒惰地将32位wchars转换为UTF16 / 8编码的资源,我觉得很有用:http://www.fileformat.info。例如。 http://www.fileformat.info/info/unicode/char/2fa1d/index.htm并向下滚动到“UTF-16(十六进制)”或“C / C ++ / Java源代码”。