首页 > 解决方案 > flex 结合 3 个不同的字母

问题描述

我想用 flex 语言匹配范围 [AE] 中的 3 个不同字母,而不重复其中的任何一个。

例如 ABC、CDE、EAB、

但不是 AAB 或 DEE。

我试过 [A|B|C|D|E]{3}、[A?B?C?D?E?]{3}、[A{0,1}-E{0,1}]{ 3},但没有工作......请帮忙!

标签: regexflex-lexerletter

解决方案


匹配三个不同字母的一种方法是拼出所有合法组合:

ABC|ABD|ABE|ACB|ACD|...  printf("Found one: %s\n", yytext);

我们可以通过对第三个字母使用字符类来缩短它:

AB[C-E]|AC[BCD]|AD[BCE]|...  printf("Found one: %s\n", yytext);

鉴于范围仅为 AE,这在一定程度上是可行的,但肯定不是很漂亮。

另一种方法是匹配超过允许的范围,然后拒绝相关操作中的非法组合。这可能看起来像这样:

[A-E]{3} {
    if (yytext[0] == yytext[1] || yytext[0] == yytext[2] || yytext[1] == yytext[2]) {
        REJECT;
    } else {
        printf("Found one: %s\n", yytext);
    }
}

REJECT将使它好像模式从未匹配过,因此这将与以前的解决方案相同。

请注意,没有什么可以阻止这些解决方案中的任何一个多次匹配模式——这毕竟是词法分析器的工作方式。所以像这样的输入ABCBCD会产生以下输出:

Found one: abc
Found one: bcd

由于您在评论中说这不是您想要的,因此您需要一个额外的规则来匹配abcbcd一个标记,然后产生一条错误消息。如果你真的只想允许只包含三个字符的输入,你可以使用.*一个模式来匹配不是 3 个非重复 AE 字符的所有内容。不过,这似乎是对 flex 的一种非常奇怪的使用。


推荐阅读