我正在尝试匹配字符串某些内容的前缀。例如,如果输入 So,SOM,SomeTH,some,S ,则全部接受,因为它们都是 Something 的前缀。
我的代码
Ss[oO]|Ss[omOMOmoM] {
printf("Accept Something": %s\n", yytext);
}
输入
Som
输出
Accept Something: So
Invalid Character
假设阅读 Som ,因为它是 Something 的前缀。我不明白为什么我的代码不起作用。有人可以纠正我在做错什么吗?
答案 0 :(得分:2)
我不知道你怎么看待
Ss[oO]|Ss[omOMOmoM]
是,但它匹配的是:
S
后跟s
,后跟字母o
或O
之一,或者S
,后跟s
,后跟字母o
,O
,m
或M
之一。在括号表达式中多次放置一个符号无效。此外,我看不到如何产生您报告的输出。也许有一个复制粘贴错误,或者说您还有其他模式规则。
如果要匹配前缀,请使用嵌套的可选匹配项:
s(o(m(e(t(h(i(ng?)?)?)?)?)?)?)?
如果要区分大小写的字符,可以写出所有字符类,但这会变得麻烦。更简单的是使用不区分大小写的标志:
(?i:s(o(m(e(t(h(i(ng?)?)?)?)?)?)?)?)
(?i:
开启i
nsensitive标志,直到匹配的右括号为止。
实际上,这可能不是您想要的。通常,您会希望将完整的单词识别为标记。然后,您可以检查规则操作中单词是否为前缀:
[[:alpha:]]+ { if (yyleng <= strlen("something") && 0 == strncasemp(yytext, "something", yyleng) {
/* do something */
}
}
Flex manual中有很多信息。
答案 1 :(得分:2)
现在,您的代码(如图所示)应仅与“ Sso”或“ SsO”或“ Ssm”或“ SsM”匹配。
您有两种选择,每种选择都以Ss
开头(不带方括号),因此它们将按字面值进行匹配。其后跟着[oO]
或[omOMomoM]
,但是方括号中的字符代表替代项,因此等效于[oOmM]
,即o
,{ {1}},O
或m
。
我将以M
开始,使其成为不区分大小写的扫描器,因此您不必列出每个字母的大小写等效项。
那么可能最简单的是按字面意思列出替代方案:
%option caseless
我想您可以通过按以下顺序进行操作来使模式更短(至少在源代码中如此):
s|so|som|some|somet|someth|somethi|somethin|something { printf("found prefix"); }
对我来说似乎不是一个很大的进步,但有些人可能会发现它比我更具吸引力。
如果您不想使用s(o(m(e(t(h(i(n(n(g)?)?)?)?)?)?)?)?)? { printf("found prefix"); }
,则基本思路可以提供更多帮助:
%option caseless
列出大写和小写的所有可能组合会很乏味。