首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >行为不当的JFlex规则-错误规则匹配

行为不当的JFlex规则-错误规则匹配
EN

Stack Overflow用户
提问于 2013-08-29 20:30:47
回答 1查看 150关注 0票数 2

我在写(简单?)JFlex标记器,其目标是取一个字符串,并将中文(或者更确切地说是使用汉字)的块和拉丁文中的部分拆开。标记器应用于品牌名称,在我的用例中,品牌名称可能同时包含拉丁语和中文名称。“联想联想”。

品牌名称还可以包含数字(7up)、连字符(惠普)、符号(P&G)等。我的标识器主要起作用,除了中文名称和非中文名称没有空格或分隔的情况外。具体而言,这些是成功和不成功分析的例子:

  • "Calvin卡尔文.克莱“--成功地分为"Calvin”和“卡尔文.克莱”,它们被标记为具有预期的脚本(拉丁语和韩语)。
  • “圣威廉”--错误地分为"圣威廉SAINT“(标记为韩语)和”圣威廉“(标记为拉丁语)。
  • “史努比史努比”--错误地认为这是一个汉代符号。

我认为我的规则是相当明确的,但结果似乎表明并非如此。这是我的规则:

代码语言:javascript
复制
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字符。由于我前面为汉字指定的一些字符范围超过了16位值,所以JFlex会感到困惑。将这些从regex中移除使其工作得很好。

参考:http://jflex.de/manual.html#SECTION000101000000000000000

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-18 19:17:11

我询问了SourceForge JFlex邮件列表上的人员,其中一位回复了我--原来是JFlex 1.4。*无法处理不能以16位表示的Unicode字符。

但它能处理好这些。

首先,让我修正一下\u2f800-u2fa1f。最后一个值确实不能在16位上表示,只是因为UNICODE块定义在\u2fa1d处停止,因此该值即使在其32位表示形式上也是无效的。

现在,说服JFlex处理问题\u2f800-\u2fa1d范围的诀窍是: Java代码(和字符串文本)使用UTF16编码的排序,因此16位“代理”(较高的UTF16单词)后面跟着其他16位配对字符。

对于您需要的范围,您是幸运的:前16位代理项在整个范围内保持不变,即\uD87E,而较低的16位在\uDC00-\uDE1D范围内变化。所以,你的韩宏变成

代码语言:javascript
复制
han   = [\u3400-\u9fff\uf900-\ufaff] | \uD87E[\uDC00-\uDE1D]

在我懒惰地将32位wchars转换为UTF16 16/8编码时,我发现了一个有用的资源:http://www.fileformat.info。例如,http://www.fileformat.info/info/unicode/char/2fa1d/index.htm和滚动到"UTF-16 (十六进制)“或"C/C++/Java源代码”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18520420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档