flex 中的多个字符串文字

multiple String literal in flex

我正在使用 flex 来解析一大堆东西,但是当我试图在同一行上检测两个字符串文字时遇到了障碍。

我的正则表达式:

["].*["]

我的意思是:

"cats" < "dogs"

被识别为一个长字符串

cats" < "dogs

为什么flex只考虑最外层的两个引号,而不是单独做两套? 我确定问题出在我的正则表达式中,所以我实质上要问的是:

如何编写一个正则表达式,在这种情况下,它会识别标记 STRING、LESS、STRING 而不仅仅是 STRING?

老实说,我不确定 flex 为什么会这样。但是要回答有关如何编写 RegEx 来检测这种情况的问题:

/^\"(?=.*[\"].*[\"].*[\"])(?=.*[\<]).+?\"$/

此 RegEx 将匹配满足这些条件的行:

  • 以引号开头和结尾
  • 第一个引号后包含3个引号(表示该行包含两个字符串)
  • 正好包含一个尖括号

因为我不知道这些是否正是您需要匹配的条件,所以我将分解这个正则表达式和一些重要的组件。

检查第一个引号后,将解析此先行子例程:

(?=.*[\"].*[\"].*[\"])

这会在 RegEx 主题中提前检查是否还有另外三个引号。它匹配任何后跟引号的内容,三次。您可以修改它以通过添加或删除 .*[\"] 部分来检查更多或更少的引号。

接下来,我们还有另一个先行子程序:

(?=.*[\<])

这会检查第一个和最后一个引号之间是否至少有一个尖括号。如果您想检查其他操作,可以将它们添加到 [\<] 的方括号内,如下所示:[\<\>\=\+].

最后,我们用.+?匹配任意字符一次或多次,后面跟最后的引号:\".

重要的是要注意,先行子例程在进行检查时实际上并不在字符串中移动。例如,如果我们使用正则表达式 /a(?=a)a/,它只会匹配两个连续的 'a' 字符,而不是三个

这就是为什么我上面提到的第一个 lookahead 试图在第一个之后找到 3 个引号。

也许不是您要找的答案,但我希望这对您有所帮助。

我想你正在使用这样的模式:

["].*["]              { return STRING; }

或者

["].*?["]             { return STRING; }

第一个行不通,因为 flex 总是采用最长的匹配,而使用最后一个 " 的匹配显然更长。第二个在常规中是正确的实现非贪婪重复的表达式库,但 flex 没有;在 flex 中,.*? 只是一个可选的 .*(也就是说,? 是一个空操作。)

您真正想要的是匹配引号以外的字符串。所以你可以这样说:

["][^"]*["]           { return STRING; }

[^"] 将匹配换行符,这与 . 不同。如果您不想要多行字符串,则必须使用 [^"\n].

显然,上面不允许 " 出现在字符串中,这迟早会很烦人。解决这个问题的两个流行的解决方案是(C 风格)到允许 \ 到 "escape" 下一个字符:("a \" in a string")

["]([^"]|\.)*["]     { return STRING; }

or (SQL-style) 要求内部 " 加倍:("a "" in a string"`)

["]([^"]|["]["])*["]  { return STRING; }