Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 正则表达式设置字符串文字的最大长度_C++_Regex_Lex_Lexical Analysis - Fatal编程技术网

C++ 正则表达式设置字符串文字的最大长度

C++ 正则表达式设置字符串文字的最大长度,c++,regex,lex,lexical-analysis,C++,Regex,Lex,Lexical Analysis,我试图找出如何在正则表达式中设置最大长度。我的目标是将字符串文本的正则表达式的最大长度设置为80 如果您需要,下面是我的表达式: ["]([^"\\]|\\(.|\n))*["]|[']([^'\\]|\\(.|\n))*['] 我尝试在表达式的前面和结尾添加{0,80},但是要么所有的字符串都分解成更小的标识符,要么到目前为止都没有 提前感谢您的帮助 编辑: 这里有一个更好的解释,我正在努力完成。 给定“此字符串长度超过80个字符”,当通过flex运行时,而不

我试图找出如何在正则表达式中设置最大长度。我的目标是将字符串文本的正则表达式的最大长度设置为80

如果您需要,下面是我的表达式:

["]([^"\\]|\\(.|\n))*["]|[']([^'\\]|\\(.|\n))*['] 
我尝试在表达式的前面和结尾添加{0,80},但是要么所有的字符串都分解成更小的标识符,要么到目前为止都没有

提前感谢您的帮助

编辑:

这里有一个更好的解释,我正在努力完成。 给定“此字符串长度超过80个字符”,当通过flex运行时,而不是像下面这样列出:

行:1,词素:|此字符串长度超过80个字符|,长度:81,标记4003

我需要像这样把它拆开:

行:1,词素:|此|,长度:1,标记6000

行:1,词素:|字符串|,长度:1,标记6000

行:1,词素:| IS |,长度:1,标记6000

行:1,词素:|超过|,长度:1,标记6000

行:1,词素:80,长度:1,标记6000

行:1,词素:|字符|,长度:1,标记6000

行:1,词素:|长|,长度:1,标记6000

而字符串“此字符串长度不超过80个字符”将显示为:


第1行,lexeme:|此字符串长度不超过80个字符|,长度:50,标记:4003

如果您在
flex
中使用正则表达式,并且需要监视其长度,最简单的方法是查看
yylex
中保存的匹配字符串(或类似内容):

我用
82
来解释两个双引号字符

如果这不是您的设置,请在评论中告诉我,我将删除我的答案(无需否决:)

如果您在
flex
中使用正则表达式,并且需要监控其长度,最简单的方法是查看
yylex
中保存的匹配字符串(或类似内容):

我用
82
来解释两个双引号字符
。 如果这不是您的设置,请在评论中告诉我,我将删除我的答案(无需否决投票:)

我尝试在表达式的前面和结尾添加
{0,80}

支撑操作符不是长度限制;这是一系列重复计数。它必须去重复操作符(
*
+
)将去的地方:在子模式被重复之后立即去

因此,在您的情况下,您可以使用:(为了清晰起见,我省略了
选项。)

[“]([^”\\\n]|\\(.|\n)){0,80}[“]
通常,我建议您不要这样做,或者至少要小心一点。(F)lex正则表达式被编译到状态转换表中,编译最大重复计数的唯一方法是为每个重复复制一次子模式状态。因此上述模式需要为
([^“\]\\\(.|\n))
(对于这样一个简单的子模式,状态崩溃可能不会太严重。但是对于更复杂的子模式,您可能会得到大量的转换表。)

编辑:将长字符串拆分为标记,就像它们没有被引用一样。 对该问题的编辑表明,我们期望的是将长度大于80个字符的字符串视为从未输入过引号;也就是说,将它们作为单独的单词和数字标记进行报告,而不插入任何空格。这对我来说太特殊了,以至于我无法说服自己正在阅读requir这是正确的,但如果我是,这里是一个可能的方法的概要

让我们假设其意图是短字符串应报告为单个标记,而长字符串应重新解释为一系列标记(可能但不一定与无引号输入产生的标记相同).如果是这样的话,确实需要指定两个词法分析,它们不会使用相同的模式规则。(首先,重新扫描需要将引号识别为文字的结尾,从而使扫描程序恢复正常处理,而原始扫描将引号视为字符串文字的开始。)

一种可能是只收集整个长字符串,然后使用不同的词汇扫描器将其分解为任何看起来有用的部分,但这需要一些复杂的管道,以便记录生成的令牌流,并将其一次返回给
yylex
调用方一个令牌。(如果
yylex
将令牌推送到解析器,这将相当容易,但这是一个完全不同的场景。)因此我将放弃这个选项,而不是提及它是可能的

因此,显然更简单的选择是确保原始扫描在第81个字符上停止,以便它可以更改词法规则并备份扫描以应用新规则

(F) lex提供了一种提供不同词汇上下文的方法。通过在(F)lex操作中使用
BEGIN
宏,可以在开始条件之间动态切换,将扫描程序切换到不同的上下文中。(它们被称为“开始条件”,因为它们更改了标记开始时扫描程序的状态。)

每个启动条件(除了名为
INITIAL
的默认启动条件)都需要在flex序言中声明。在这种情况下,我们只需要一个额外的启动条件,我们称之为
SC\u LONG\u STRING
。(按照惯例,开始条件名称写在所有大写字母中,因为它们被转换为C宏或枚举值。)

Flex有两种可能的备份扫描的机制,其中一种在这里都可以使用。我将展示显式备份,因为它更安全、更灵活;另一种方法是使用尾部上下文操作符(
/
),它在这个解决方案中可以很好地工作,但在其他情况下则不行
["]([^"\\]|\\(.|\n))*["]|[']([^'\\]|\\(.|\n))*[']    { if (strlen(yylex) > 82) { ... } }
%x SC_LONG_STRING
%%
["]([^"\\\n]|\\(.|\n)){0,80}["]    { yylval.str = strndup(yytext + 1, yyleng - 2);
                                     return TOKEN_STRING; 
                                   }
["]([^"\\\n]|\\(.|\n)){81}         { BEGIN(SC_LONG_STRING); yyless(1); }
["]([^"\\\n]|\\(.|\n)){0,80}       { yyerror("Unterminated string"); }
<SC_LONG_STRING>["]                      { BEGIN(INITIAL); }
<SC_LONG_STRING>[ \t]+                   ;
<SC_LONG_STRING>([^"\\ \n\t]|\\(.|\n))+  { yylval.str = strdup(yytext);
                                           return TOKEN_IDENTIFIER;
                                         }
<SC_LONG_STRING>\n                       |
<SC_LONG_STRING><<EOF>>                  { yyerror("Unterminated string"); }