问题描述
我正在尝试使用 FLEX 来识别我需要的一些正则表达式。
我要找的是一组字符,比如说[A-Z]
,我想要一个正则表达式,无论它是什么,都可以匹配第一个字母,然后是第二个字母,可以是{{1} } 除了第一个字母。
例如,如果我给你 [A-Z]
,你匹配它但如果我给你 AB
你不匹配。所以我正在寻找一个类似的正则表达式
AA
除了第一组选的东西[A-Z][A-Z^
。
对于更多出现的字母,如何实现?假设我想匹配 3 个字母而不是每个新字母都来自以前的字母。例如 ]
但不是 ABC
。
谢谢!
解决方法
(数学)正则表达式没有上下文。在 (f)lex 中——正则表达式实际上是正则的,与大多数正则表达式库不同——没有反向引用,正面或负面。
因此,使用 flex 模式实现目标的唯一方法是枚举可能性,这对于两个字母来说是乏味的,而对于更多字母则不切实际。两个字母的大小写类似于(缩写);
A[B-Z]|B[AC-Z]|C[ABD-Z]|D[A-CE-Z]|…|Z[A-Y]
逆表达式也有 26 种情况,但更容易输入(和阅读)。您可以使用 (f)lex 的 first-longest-match 规则来利用它:
AA|BB|CC|DD|…|ZZ { /* Two identical letters */ }
[[:upper:]]{2} { /* This is the match */ }
可能,这两个都不是最好的解决方案。但是,我不认为我可以在不了解更多细节的情况下提供更好的建议。关键是知道如果字母匹配,你想采取什么行动,你没有指定。以及其他模式是什么。 (回想一下,词法扫描器旨在将输入划分为标记,尽管一旦识别出标记,您就可以随意忽略它。)
Flex 确实提供了许多有用的功能,可用于更灵活的令牌处理,包括 yyless
(重新扫描部分或全部令牌)、yymore
(将匹配与下一个标记)和 unput
(将字符插入到输入流中)。还有REJECT
,但您应该先尝试其他解决方案。有关详情,请参阅 the flex manual chapter on actions。
所以最简单的解决方案可能是匹配任意两个大写字母,然后在动作中检查它们是否相同。