0

我正在尝试匹配字符串Something的前缀。例如,如果输入So,SOM,SomeTH,some,S,则都被接受,因为它们都是Something的前缀。

我的代码

Ss[oO]|Ss[omOMOmoM] {
        printf("Accept Something": %s\n", yytext);
}

输入

Som

输出

Accept Something: So
Invalid Character

假设阅读Som因为它是Something的前缀。我不明白为什么我的代码不起作用。谁能纠正我做错了什么?

4

2 回答 2

2

现在你的代码(如图所示)应该只匹配“Sso”或“SsO”或“Ssm”或“SsM”。

您有两个备选方案,每个备选方案都以Ss(不带方括号)开头,因此它们将按字面意思匹配。后面是[oO]or ,但方括号中的字符表示替代项,[omOMomoM]因此相当于 --即,或[oOmM]的任何一个字符。oOmM

我将从:%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基本思想,则更有帮助:

[sS]([oO]([mM]([eE]([tT]([hH]([iI]([nN]([gG])?)?)?)?)?)?)?)? { printf("found prefix"); }

列出大写和小写的所有可能组合将变得乏味。

于 2018-10-02T05:07:03.177 回答
2

不知道你觉得什么意思

Ss[oO]|Ss[omOMOmoM]

是,但它匹配的是:

  • anS后跟 ans后跟一个字母oor O, 或
  • anS后跟 ans后跟恰好一个字母o, O,mM。在括号表达式中多次放置一个符号没有效果。

另外,我看不出这会如何产生您报告的输出。也许存在复制和粘贴错误,或者您有其他模式规则。

如果要匹配前缀,请使用嵌套的可选匹配:

s(o(m(e(t(h(i(ng?)?)?)?)?)?)?)?

如果你想要不区分大小写的匹配,你可以写出所有的字符类,但这很麻烦;更简单的是使用不区分大小写的标志:

(?i:s(o(m(e(t(h(i(ng?)?)?)?)?)?)?)?)

(?i:打开insensitive 标志,直到匹配的右括号。

实际上,这可能不是您想要的。通常,您需要将完整的单词识别为标记。然后,您可以检查该单词是否是规则操作中的前缀:

[[:alpha:]]+    { if (yyleng <= strlen("something") && 0 == strncasemp(yytext, "something", yyleng) { 
                  /* do something */
                  } 
                }

Flex 手册中有很多信息。

于 2018-10-02T05:06:22.343 回答