[英]Regex in jFlex with hardcoded exceptions
我需要在jFlex中使用一个正则表达式来匹配包含一些字符的字符串文字,然后是一个连字符,再加上一个单词。 但是,有一些硬编码的例外。 我的jFlex版本是1.6.1
我的正则表达式是:
SUFFIXES = labeled|deficient
ALPHANUMERIC = [:letter:]|[:digit:]
AVOID_SUFFIXES = {SUFFIXES} | !({ALPHANUMERIC}+)
WORD = ({ALPHANUMERIC}+([\-\/\.]!{AVOID_SUFFIXES})*)
字符串"MXs12-labeled"
应标记为'MXs12', '-', 'labeled'
(以后由不同的正则表达式捕获的连字符),而"MXs12-C123"
为'MXs12-C123'
因为C123不在后缀列表中。
但是,我获得的令牌是"MXs12-labele"
- "MXs12-labele"
外禁止的字母短一个字母。
一个明显的解决方案是在正则表达式中包含其他非{ALPHANUMERIC}
字符,但这也会将该字符添加到匹配项中。
另一个解决方案似乎是使用负前瞻,但是每次我尝试解析它们时它们都返回语法错误-jFlex似乎不支持它。 ( Flex似乎不支持regex超前断言(快速lex分析器) )
有人知道如何在jFlex中解决此问题吗?
如您所见,使用正匹配比使用负匹配要容易得多。 (显然, labele
与labeled
不匹配,而且它是labeled
的最长前缀,与labeled
不匹配,因此逻辑上是,如果尝试匹配!labeled
的单词, labele
作为匹配项。
JFlex不会实现否定的超前断言,该断言虽然稍有不同,但仍然存在问题。 负前向断言肯定会拒绝后缀MXs12-labeled
,但它也将拒绝在后缀MXs12-labeledblack
,这将是一个有点出人意料,我想。
但是,如果您用积极的比赛改写它,那真的很简单。 这个想法是指定每次正面比赛需要做什么。 在这种情况下,我们会想用的正赛做-labeled
是把它放回输入流,这是可以做到的yypushback
。 这将建议规则如下:
{ALPHANUMERIC}+ ({DELIMITER}{ALPHANUMERIC}+)* "-labeled" { yypushback(8); /* return the WORD */ }
{ALPHANUMERIC}+ ({DELIMITER}{ALPHANUMERIC}+)* "-deficient" { yypushback(10); return /* return the WORD */ }
{ALPHANUMERIC}+ ({DELIMITER}{ALPHANUMERIC}+)* { return /* return the WORD */ }
请注意,顺序很重要,因为该序列依赖于优先级高于最后一个模式的前两个模式。 (与前两个模式之一匹配的输入也将与最后一个模式匹配,但是按指示顺序的规则,最后一个模式将不会获胜。)
那可能不是您真正想要的。 它将处理您的问题中指示的MXs12-labeled
和MXs12-C123
。 MXs12-labeledblack
MXs12-labeled-black
和MXs12-labeled-black
都将作为单个令牌进行报告; 我不清楚您对这些投入的期望是什么。
Rici的答案解决了这个问题yypushback()
正是我所需要的。 截至目前
yypushback()
的输出部分中还有其他Java正则表达式,检查字符串是否有后缀,如果有则使用yypushback()
。 通过使用其他Java正则表达式,我可以涵盖上述的MXs12-labeled-black
情况,例如"\\\\-labeled$"
确保后缀位于传递的字符串的末尾,并且MXs12-labeled-black
将作为一个令牌返回,而MXs12-labeled
为三个令牌。 。 非常感谢你!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.