You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flex/Lex匹配含重复大写字母的2-8位字符串遇编译问题求助

问题分析与解决

代码编译错误原因

你的Flex代码存在几个关键语法问题,导致编译报错或卡住:

  • 不支持Perl风格大小写不敏感语法:Flex原生不支持(?i:...)这种PCRE风格正则,要实现大小写不匹配,需添加%option caseless选项,而非在宏定义里写(?i:...)。
  • 宏定义拼写错误:hexagon (?i:pehagon)里的pehagon是笔误,应为hexagon。
  • 正则语法冗余:第24行正则末尾的\n属于多余字符,Flex规则匹配输入流内容,换行符会被单独处理,无需写在正则中。
  • 规则顺序不合理:Flex遵循「最长匹配+顺序优先」原则,错误提示规则应放在正确匹配规则之前,否则会被后面的通用规则覆盖。

修复后的代码

%option caseless
%{
%}

/* 几何实体宏定义 */
point       point
line        line
triangle    triangle
square      square
pentagon    pentagon
hexagon     hexagon
heptagon    heptagon
octagon     octagon

%%
/* 错误:只输入几何实体,未输入名称 */
^[ \t]*({point}|{line}|{triangle}|{square}|{pentagon}|{hexagon}|{heptagon}|{octagon})[ \t]*$ 
    printf("你忘记输入几何实体的名称了,比如 triangle ABC,请重试。\n\n");

/* 错误:只输入名称,未输入几何实体 */
^[ \t]*[A-Z]{1,8}[ \t]*$ 
    printf("你忘记输入几何实体类型了,比如 triangle,请重试。\n\n");

/* 错误:名称包含小写字母 */
^[ \t]*({point}|{line}|{triangle}|{square}|{pentagon}|{hexagon}|{heptagon}|{octagon})[ \t]*[a-z]+[ \t]*$ 
    printf("几何实体名称只能用大写字母,请使用A-Z的字符重试。\n\n");

/* 错误:名称长度不符合对应实体要求 */
{point}[ \t]*[A-Z]{2,}|{line}[ \t]*[A-Z]{1}|{line}[ \t]*[A-Z]{3,}|{triangle}[ \t]*[A-Z]{1,2}|{triangle}[ \t]*[A-Z]{4,}|{square}[ \t]*[A-Z]{1,3}|{square}[ \t]*[A-Z]{5,}|{pentagon}[ \t]*[A-Z]{1,4}|{pentagon}[ \t]*[A-Z]{6,}|{hexagon}[ \t]*[A-Z]{1,5}|{hexagon}[ \t]*[A-Z]{7,}|{heptagon}[ \t]*[A-Z]{1,6}|{heptagon}[ \t]*[A-Z]{8,}|{octagon}[ \t]*[A-Z]{1,7}|{octagon}[ \t]*[A-Z]{9,} 
    printf("几何实体名称无效,请重试。\n\n");

/* 错误:名称包含重复字母 */
([A-Z]*A[A-Z]*A[A-Z]*)|([A-Z]*B[A-Z]*B[A-Z]*)|([A-Z]*C[A-Z]*C[A-Z]*)|([A-Z]*D[A-Z]*D[A-Z]*)|([A-Z]*E[A-Z]*E[A-Z]*)|([A-Z]*F[A-Z]*F[A-Z]*)|([A-Z]*G[A-Z]*G[A-Z]*)|([A-Z]*H[A-Z]*H[A-Z]*)|([A-Z]*I[A-Z]*I[A-Z]*)|([A-Z]*J[A-Z]*J[A-Z]*)|([A-Z]*K[A-Z]*K[A-Z]*)|([A-Z]*L[A-Z]*L[A-Z]*)|([A-Z]*M[A-Z]*M[A-Z]*)|([A-Z]*N[A-Z]*N[A-Z]*)|([A-Z]*O[A-Z]*O[A-Z]*)|([A-Z]*P[A-Z]*P[A-Z]*)|([A-Z]*Q[A-Z]*Q[A-Z]*)|([A-Z]*R[A-Z]*R[A-Z]*)|([A-Z]*S[A-Z]*S[A-Z]*)|([A-Z]*T[A-Z]*T[A-Z]*)|([A-Z]*U[A-Z]*U[A-Z]*)|([A-Z]*V[A-Z]*V[A-Z]*)|([A-Z]*W[A-Z]*W[A-Z]*)|([A-Z]*X[A-Z]*X[A-Z]*)|([A-Z]*Y[A-Z]*Y[A-Z]*)|([A-Z]*Z[A-Z]*Z[A-Z]*) 
    printf("哦!你输入了重复的字母,请重试:%s\n", yytext);

/* 正确:匹配几何实体 */
{point}|{line}|{triangle}|{square}|{pentagon}|{hexagon}|{heptagon}|{octagon} 
    printf("---> %s: 是几何实体。\n", yytext);

/* 正确:匹配几何实体名称(长度1-8的大写字母) */
[A-Z]{1,8} 
    printf("---> %s: 是几何实体的名称。\n\n", yytext);

/* 忽略空白字符 */
[ \t\n]+

/* 匹配其他所有字符 */
.+
%%

int main(){
    yylex();
    return 0;
}

匹配长度2-8且包含重复[A-Z]字母的字符串

由于Flex不支持正向预查等高级正则特性,最直接的方式是枚举每个大写字母的重复场景,确保整体长度在2-8之间——上面修复后的代码已经通过([A-Z]*X[A-Z]*X[A-Z]*)的形式实现了这一点,枚举A到Z每个字母的重复情况,覆盖所有含至少一个重复大写字母、长度2-8的字符串。

如果觉得枚举太冗长,也可以在匹配到长度2-8的大写字母串后,用代码检查重复字符:

[A-Z]{2,8} {
    int seen[26] = {0};
    int has_duplicate = 0;
    for (int i = 0; yytext[i]; i++) {
        int idx = yytext[i] - 'A';
        if (seen[idx]) {
            has_duplicate = 1;
            break;
        }
        seen[idx] = 1;
    }
    if (has_duplicate) {
        printf("匹配到含重复字母的字符串:%s\n", yytext);
    }
}

内容的提问来源于stack exchange,提问作者Vaggelis Manousakis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 23:10:26