问题描述
我正在尝试创建一个正则表达式,以验证给定的字符串仅具有char文字或转义序列,并且转义序列可以为'\ t','\\','\''和'\ * *',其中**是介于0到5之间的1或2位数字的序列。
示例:
1。 '!' = true;
2。 '\a' = false;
3。 '\26' = false;
4。 '\\' = true;
5。 '\\\t' = false;
6。 '\15' = true;
7。 'a' = true;
8。 'aa' = false;
这是到目前为止我所拥有的一个例子,但是不能正常工作
escape \\(t|\\|\'|[0-5]{1,2})
\' \\begins CHARLIteraL
<CHARLIteraL>[^\n\']|{escape} \\True condition
<CHARLIteraL>[^t\\\'\n]|\\[0-9]+ \\False condition
<CHARLIteraL>\' \\End CHARLIteraL
<CHARLIteraL>\n \\Unterminated
<CHARLIteraL><<EOF>> \\Unterminated
解决方法
我认为没有字符文字的起始条件,更容易解决这个特定问题。由于您要确保在单引号之间只显示单个代码(字符或转义符),因此您的成功模式应同时包含开始和结束的单引号:
/* ' does not have any special meaning to (f)lex so it does not have to be escaped */
'(['^\n\\]|\\([t'\\]|[0-5]{1,2}))' { printf("CHARLITERAL: %s\n",yytext); }
由于可以匹配任何正确的字符文字,因此只需匹配单引号就可以检测不正确的文字;该模式只会在不再匹配时触发:
' { printf("Invalid CHARLITERAL\n"); }
/* But see below */
唯一的问题是找出出现错误后如何继续扫描,因为一旦发现错误,您就无法确定正确的输入。您所能做的只是猜测。 (当然,如果解析器不知道如何进行错误恢复,那完全是理论上的。遇到第一个错误时,您可以停止扫描。)
一个简单的猜测(通常会起作用)是跳过字符,直到找到'
或换行符为止。如果错误是缺少结束的引号,则可能会跳过太多,但是不会跳过太多,因为最多只会跳过其余部分。
在这里,您可以利用开始条件:
'(['^\n\\]|\\([t'\\]|[0-5]{1,yytext); }
' { BEGIN(BAD_CHAR_LITERAL); }
<BAD_CHAR_LITERAL>[^'\n]*'? { printf("Bad CHARLITERAL: Skipping '%s\n",yytext);
BEGIN(INITIAL);
}
<BAD_CHAR_LITERAL><<EOF>> { printf("Trailing single quote\n");
return 0;
}
BAD_CHARACTER_LITERAL
中的模式跳过该行的其余部分,或者跳过并包括下一个单引号。在第一种情况下,它将换行符保留为默认扫描仪状态。
或者,您可以使用input()
来从输入流中读取字符,直到找到'
或\n
(或EOF)为止。