Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.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++;for&;while循环 在Python应用程序中,我需要编写一个与C++代码< > > >代码> >的正则表达式,而循环已经用一个半冒号终止了(;)。例如,它应该与以下内容匹配: for (int i = 0; i < 10; i++);_C++_Python_Regex_Parsing_Recursion - Fatal编程技术网

用于检测以分号结尾的C++;for&;while循环 在Python应用程序中,我需要编写一个与C++代码< > > >代码> >的正则表达式,而循环已经用一个半冒号终止了(;)。例如,它应该与以下内容匹配: for (int i = 0; i < 10; i++);

用于检测以分号结尾的C++;for&;while循环 在Python应用程序中,我需要编写一个与C++代码< > > >代码> >的正则表达式,而循环已经用一个半冒号终止了(;)。例如,它应该与以下内容匹配: for (int i = 0; i < 10; i++);,c++,python,regex,parsing,recursion,C++,Python,Regex,Parsing,Recursion,有人能建议对这个正则表达式进行改进吗?这对我来说太复杂了,我想不起来了。这是你真的不应该用正则表达式做的事情。只需一次解析一个字符的字符串,跟踪开始/结束括号 如果你只想找到这个,你肯定不需要一个完整的C++语法词典/解析器。如果你想练习的话,你可以编写一个简单的递归语法分析器,但是仅仅匹配括号就有点难了。这是一个使用错误工具的好例子。正则表达式不能很好地处理任意嵌套的子匹配。你应该做的是使用一个真正的词法分析器和语法分析器(C++的语法应该很容易找到),并且寻找意想不到的空循环体。 < P>我

有人能建议对这个正则表达式进行改进吗?这对我来说太复杂了,我想不起来了。

这是你真的不应该用正则表达式做的事情。只需一次解析一个字符的字符串,跟踪开始/结束括号


如果你只想找到这个,你肯定不需要一个完整的C++语法词典/解析器。如果你想练习的话,你可以编写一个简单的递归语法分析器,但是仅仅匹配括号就有点难了。

这是一个使用错误工具的好例子。正则表达式不能很好地处理任意嵌套的子匹配。你应该做的是使用一个真正的词法分析器和语法分析器(C++的语法应该很容易找到),并且寻找意想不到的空循环体。

< P>我甚至不注意父母的内容。 只需匹配以开头,以分号结尾的任何行即可:

^\t*for.+;$

除非您将
for
语句拆分为多行,否则这样做很好?

Greg绝对正确。这种解析不能用正则表达式完成。我想有可能建立一些可怕的怪物,在很多情况下都能工作,但是你会遇到一些这样的东西


您确实需要使用更传统的解析技术。例如,编写一个递归解析器来完成您需要的工作非常简单

我不知道正则表达式是否能很好地处理这样的事情。试试这样的

line = line.Trim();
if(line.StartsWith("for") && line.EndsWith(";")){
    //your code here
}

您可以编写一个小的、非常简单的例程来执行此操作,而无需使用正则表达式:

  • 设置位置计数器
    pos
    ,使其指向
    for
    while
    后面的开口支架前面
    
  • 将开括号计数器
    openBr
    设置为
    0
  • 现在,继续递增
    pos
    ,读取相应位置的字符,并在看到左括号时递增
    openBr
    ,在看到右括号时递减。这将在开始时增加它一次,对于“
    for(
    ”)中的第一个开口括号,对中间的一些括号再增加和减少一些,并在
    for
    括号关闭时将其设置回
    0
  • 因此,当
    openBr
    再次为
    0
    时停止

停止位置是(…)
的结束括号。

现在可以检查后面是否有分号。

另一种想法是忽略括号并将的
视为包含三个分号分隔值的构造:

for\s*\([^;]+;[^;]+;[^;]+\)\s*;
此选项即使在拆分多行时也有效(启用多行后),但假定(…;…;…)
是唯一有效的构造,因此不适用于(x in y)
构造或其他偏差

还假设没有包含分号作为参数的函数,例如:

for ( var i = 0; i < ListLen('a;b;c',';') ; i++ );
for(var i=0;i
这种情况是否可能发生取决于您实际执行此操作的目的。

请尝试使用此regexp

^\s*(for|while)\s*
\(
(?P<balanced>
[^()]*
|
(?P=balanced)
\)
\s*;\s
^\s*(用于| while)\s*
\(
(?P
[^()]*
|
(?P=平衡)
\)
\s*;\s

我移除了
\(\)
环绕
(?p=balanced)
的包装,并将
*
移动到any not paren序列的后面。我使用boost xpressive进行了这项工作,并重新检查了该网站()以刷新我的记忆。

正如Frank所建议的,最好不要使用正则表达式。下面是(一个丑陋的)一行:

match_string = orig_string[orig_string.index("("):len(orig_string)-orig_string[::-1].index(")")]
与他评论中提到的巨魔路线est相匹配:

orig_string = "for (int i = 0; i < 10; doSomethingTo(\"(\"));"
match_string = orig_string[orig_string.index("("):len(orig_string)-orig_string[::-1].index(")")]
orig\u string=“for(inti=0;i<10;doSomethingTo(\”(\”);”
match_string=orig_string[orig_string.index(“”):len(orig_string)-orig_string[::-1]。index(“”))
返回
(int i=0;i<10;doSomethingTo(“”)


它的工作原理是向前遍历字符串,直到它到达第一个打开的paren,然后向后遍历字符串,直到它到达第一个关闭的paren。然后它使用这两个索引对字符串进行切片。

有点晚了,但我认为正则表达式不是执行此任务的合适工具

问题是,您会遇到边缘情况,这会给正则表达式增加额外的复杂性。提到:

for(int i=0;i<10;doSomethingTo(“”);
此字符串文字包含(不平衡!)括号,这会破坏逻辑。显然,您必须忽略字符串文字的内容。为此,必须考虑双引号。但字符串文字本身可以包含双引号。例如,请尝试以下操作:

for (int i = 0; i < 10; doSomethingTo("\"(\\"));
for(int i=0;i<10;doSomethingTo(\”(\”));
如果您使用正则表达式来解决这个问题,它将给您的模式增加更多的复杂性

我认为你最好用解析语言。例如,你可以使用一个语言识别工具,比如ANTLR。ANTLR是一个解析器生成器工具,它也可以生成一个。你必须提供一个定义目标语言的语法,在你的情况下C++。已经有很多语法在那里,所以你可以抓取。>


然后,您可以轻松地遍历解析器树,搜索空语句,如
,而
查找
循环体。

+1,严格来说,正则表达式根本不处理嵌套表达式。处理嵌套表达式的正则表达式已超越为上下文无关语法。我同意使用flex/yacc或类似的方法。但它是C++语法真的很容易找到吗?
for ( var i = 0; i < ListLen('a;b;c',';') ; i++ );
^\s*(for|while)\s*
\(
(?P<balanced>
[^()]*
|
(?P=balanced)
\)
\s*;\s
match_string = orig_string[orig_string.index("("):len(orig_string)-orig_string[::-1].index(")")]
orig_string = "for (int i = 0; i < 10; doSomethingTo(\"(\"));"
match_string = orig_string[orig_string.index("("):len(orig_string)-orig_string[::-1].index(")")]
for (int i = 0; i < 10; doSomethingTo("("));
for (int i = 0; i < 10; doSomethingTo("\"(\\"));