当前位置:  开发笔记 > 编程语言 > 正文

正则表达式检测用于&while循环的半冒号终止C++

如何解决《正则表达式检测用于&while循环的半冒号终止C++》经验,为你挑选了3个好方法。

在我的Python应用程序中,我需要编写一个匹配C++ forwhile循环的正则表达式,该循环使用分号(;).例如,它应匹配此:

for (int i = 0; i < 10; i++);

......但不是这个:

for (int i = 0; i < 10; i++)

这看起来很琐事,直到您意识到开括号和右括号之间的文本可能包含其他括号,例如:

for (int i = funcA(); i < funcB(); i++);

我正在使用python.re模块.现在我的正则表达式看起来像这样(我已经留下了我的评论,所以你可以更容易理解):

# match any line that begins with a "for" or "while" statement:
^\s*(for|while)\s*
\(  # match the initial opening parenthesis
    # Now make a named group 'balanced' which matches a balanced substring.
    (?P
        # A balanced substring is either something that is not a parenthesis:
        [^()]
        | # …or a parenthesised string:
        \( # A parenthesised string begins with an opening parenthesis
            (?P=balanced)* # …followed by a sequence of balanced substrings
        \) # …and ends with a closing parenthesis
    )*  # Look for a sequence of balanced substrings
\)  # Finally, the outer closing parenthesis.
# must end with a semi-colon to match:
\s*;\s*

这适用于所有上述情况,但只要你尝试使for循环的第三部分包含一个函数就会中断,如下所示:

for (int i = 0; i < 10; doSomethingTo(i));

我认为它会中断,因为只要在开括号和右括号之间放置一些文本,"平衡"组就会匹配包含文本,因此该(?P=balanced)部分不再起作用,因为它不匹配(由于事实括号内的文字是不同的).

在我的Python代码中,我使用VERBOSE和MULTILINE标志,并创建正则表达式,如下所示:

REGEX_STR = r"""# match any line that begins with a "for" or "while" statement:
^\s*(for|while)\s*
\(  # match the initial opening parenthesis
    # Now make a named group 'balanced' which matches
    # a balanced substring.
    (?P
        # A balanced substring is either something that is not a parenthesis:
        [^()]
        | # …or a parenthesised string:
        \( # A parenthesised string begins with an opening parenthesis
            (?P=balanced)* # …followed by a sequence of balanced substrings
        \) # …and ends with a closing parenthesis
    )*  # Look for a sequence of balanced substrings
\)  # Finally, the outer closing parenthesis.
# must end with a semi-colon to match:
\s*;\s*"""

REGEX_OBJ = re.compile(REGEX_STR, re.MULTILINE| re.VERBOSE)

任何人都可以建议改进这个正则表达式吗?对我来说,让我的头脑变得过于复杂.



1> Frank..:

您可以编写一个非常简单的例程,而不使用正则表达式:

设置一个位置计数器pos,使其指向您for或之后的开始括号之前while.

设置一个开放的括号计数器openBr0.

现在继续递增pos,读取相应位置的字符,并openBr在看到左括号时递增,并在看到右括号时递减.这将在开头增加一次,对于" for ("中的第一个开括号,对于其间的一些括号增加和减少一些,并0for括号关闭时将其设置回.

所以,不要当openBr0一次.

停止位置是你的结束for(...).现在您可以检查是否有分号.


拖钓线:`for(int i = 0; i <10; doSomethingTo("("));`
您还需要考虑注释和字符串,这两者都将引发此算法.
您可以使用正则表达式预先删除注释和字符串.:)或者引入更多变量,比如openBr,它表明你是否在评论中(以及什么类型的评论,所以你知道什么字符关闭它)或字符串.

2> Jesse Beder..:

这是你不应该用正则表达式做的事情.只需一次解析字符串一个字符,跟踪打开/关闭括号.

如果您正在寻找这个,那么您绝对不需要一个完整的C++语法词法分析器/解析器.如果你想练习,你可以编写一个小的递归式解析器,但即便如此,只需匹配括号.



3> Greg Hewgill..:

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

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有