对包含连字符和斜杠的字母数字字符串进行积极前瞻断言的 Flex 词法分析器规则

Flex lexer rule with positive lookahead assertion on alphanumeric strings containing hyphens and slashes

我在为某种类型的令牌构建具有正面前瞻断言的 flex lexer 规则时遇到了一些麻烦,需要一些帮助。我确定我在这里遗漏了一些简单的东西。

我要匹配的令牌字符串如下所示:

33-abc-13/12
99-ab-33
o3sehh04/00
glu6-840d/00
vm-22hd
xyz-3

要匹配的令牌对象是一个包含 letters and digits 的字符串,并且有 slashes and/or hyphens,极少数情况 a dot,可能类似于 xx-3006/10.00

不能匹配的(因为其他规则涵盖这些情况)是以下标记:

numeric370
hyphen-term
plainterm
00/40

到目前为止,我尝试过的是这条具有前瞻性的规则:

([a-z0-9/-]*)/[-/]+[0-9/-]+

通过以上,我得到的结果接近我想要达到的结果。它匹配上面列出的所有这些字符串,但会跳过最后一个字符或数字。匹配的标记如下所示:

33-abc-13/1
o3sehh04/0
...

不幸的是,该规则也匹配 00/40(导致 00/4)。

所以我的问题是我在这里想念什么?如果可能并且速度足够快,最好用一个规则来涵盖这些情况。我知道词法分析器脚本中处理规则的顺序,因此该规则的位置将是整个集合中的第一个。 如果不可能,也许打破该规则是另一种方法。

在这个项目中,我使用了 RE-flex 包 (https://github.com/Genivia/RE-flex),因为它涵盖了 flex lexer 接口并提供了 unicode(我需要使用 wchar_t 字符串)。 我的词法分析器是一个带有标记分类的空白标记器,它基本上是在几年前构建在 flex 2.5 包上的。我在令牌处理中重构了一些东西,并转向 re-flex,因为它为我提供了更多机会。 tokenizer 输入字符串是简短的简单文本片段,它们的长度不超过 250-300 个字符。背景介绍到此为止。

注意:在为词法分析器转换规则之前,我在构建规则时使用 regex101.com 到 check/experiment。它有助于找到正确的方向,但仅此而已。

非常感谢任何帮助,感谢您提前的努力!

更新: 根据 rici 的回答,最终模式现在看起来像这样:

[a-z0-9/.-]*[/.-][0-9/-]+

这也包括现在包含 . 的标记,例如

xx33-4.00
f/44-7.87
...

考虑到我下面评论中的句子分隔符问题很简单 模式的最后一个字符组中的 .。我删除了它,现在它按预期工作了。

我对 RE-flex 一无所知(虽然它看起来很酷)但假设它确实与 flex 兼容,同样的方法应该有效:忘记前瞻性断言(因为匹配的字符串将 not 包含前瞻模式,并且您想匹配整个字符串)并将规则 放在 所有其他可能匹配相同内容的规则之后。

弹性规则是:

  • 匹配时间最长的模式获胜,但是
  • 如果两个或多个模式都匹配最长的匹配项,则文件中的第一个模式获胜。

例如,假设您有以下模式:

[0-9]+("/"[0-9]+)*          { return SLASHED_NUMBERS; }
[a-z0-9/-]*[/-][0-9/-]+     { return GENERAL_TOKEN;   }

[注1]

两者都将匹配 00/40,因此如果这是输入点的标记,则该标记将被检测为 SLASHED_NUMBERS(文件中的第一个规则)。另一方面,如果您有 00/49-23,它将被检测为 GENERAL_TOKEN,因为该规则匹配了更多字符。


备注

  1. 我基于你的正则表达式。我不明白“罕见的情况下一个点”,它似乎没有反映在你的模式中;此外,您的模式似乎比“字母、数字、连字符和斜杠”更具体,但我不确定具体是什么。