Flex 词法分析器规则,对包含连字符和斜杠的字母数字字符串具有积极的前瞻断言
Flex lexer rule with positive lookahead assertion on alphanumeric strings containing hyphens and slashes
我很难为某种类型的令牌构建一个具有积极前瞻性断言的 flex 词法分析器规则,并且可能需要一些帮助。我确定我在这里错过了一些简单的东西。
我要匹配的令牌字符串如下所示:
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 词法分析器接口并提供 unicode(我需要处理wchar_t
字符串)。 我的词法分析器是一个带有标记分类的空格标记器,它基本上是在几年前的 flex 2.5 包上构建的。我在令牌处理中重构了一些东西,并转向重新弯曲,因为它给了我更多的机会。分词器输入字符串是简短的简单文本片段,它们的长度不超过 250-300 个字符。到目前为止的背景。
注意:在为词法分析器转换规则之前,我在构建规则时使用 regex101.com 进行检查/实验。它有助于达到正确的方向,但仅此而已。
任何帮助都非常感谢,提前感谢您的努力!
更新:根据 rici 的回答,最终模式现在如下所示:
[a-z0-9/.-]*[/.-][0-9/-]+
这也包括现在包含.
的令牌,例如
xx33-4.00
f/44-7.87
...
考虑到我下面评论中的句子分隔符问题只是 模式最后一个字符组中的.
。我删除了它,现在它按预期工作。
我对 RE-flex 一无所知(尽管它看起来很酷),但假设它确实与 flex 兼容,同样的方法应该有效:忘记前瞻断言(因为匹配的字符串将不包括前瞻模式,并且您希望匹配整个字符串)并将规则放在所有其他可能匹配相同事物的规则之后。
弹性规则为:
- 比赛时间最长的模式获胜,但
- 如果两个或多个模式都匹配最长匹配项,则文件中的第一个模式优先。
因此,例如,假设您有以下模式:
[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
,因为该规则匹配了更多字符。
注释
- 我基于您的正则表达式。我不明白"罕见的情况一个点",它似乎没有反映在你的模式中;此外,您的模式似乎比"字母、数字、连字符和斜杠"更具体,但我不确定具体是什么。
- C++,在int数组中输入字符串或字符会输出0,而不是ascii或error
- 字符串操作 - 字符计数
- 我的目标是编写一个程序来计算和存储字符串在字符数组中出现的位置
- 在C++中使用 UTF-8 字符串和字符
- 如何使用SQLite将数据库中的值导出为C / C++中的字符串或字符?
- 递归形成字符串中所有数字字符的中间和?
- 如何在C++中为字符串添加字符?
- C++ 无法将 std::vector<BYTE> 转换为字符串或字符数组
- C++完全复制要字符串的字符列表,而不会忽略多个空格
- 我如何知道字符串中字符相对于英文字母的位置值?
- 如何将 VB.Net 字符串作为字符*传递给C++dll?
- 有没有办法将最初作为字符串输入的数字字符数组复制到双向链表中
- 如何使用 c++ 将数字字符转换为字符串
- 使用find_if和isalnum在字符串中找到字母数字字符
- 在没有字符串或字符帮助的情况下查找数字的反面(例如:2500 reverse 0025)
- 确保字符串只包含字母数字字符的更好方法
- 在检测字符串是否包含数字字符时,这有什么问题
- 为什么我无法擦除字符串的数字字符?
- if语句-测试字符串或字符的大写,小写和数字
- 如何在 c++ 中从字符串中删除所有非字母数字字符