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; }
我正在使用 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; }