我正在尝试编写一个正则表达式来搜索从C ++源代码文件中读取的字符串中的/ if / while关键字,但不包括任何包含它们的单词:
WhatifYes()
Whatfor()
Waitforwhile()
我写了下面的正则表达式:
if { [ regexp {(for|while|if)(\s+)(\()} $lineValue ] } {
但它并没有像以下那样收集案件:
while(( int x = 0 ) > 0 );
while(( int x = 0 ) > 0 )
for(int y =0 ; ; )
for(int y =0 ; ; );
if( (int x = 9) > 0 )
if( (int x = 9) > 0 );
最初我认为因为我的正则表达式被定义为:
if/for/while \s+ ( #space or multiple spaces
但我尝试在上面的示例中包含空格:
while (( int x = 0 ) > 0 );
while (( int x = 0 ) > 0 )
if ( (int x = 9) > 0 )
if ( (int x = 9) > 0 );
仍然正在使用正则表达式 - 请让我知道我应该使用什么正则表达式捕获它们?
答案 0 :(得分:4)
您的部分问题很容易解决,部分内容非常困难。
简单的部分是确保你有一个完整的词:\m
约束转义只在一个单词的开头匹配,而\M
约束转义匹配在结尾,所以我们可以使用:
# Nothing capturing; you can add that as necessary
# Ellipsis for the bits I've not talked about yet
regexp {\m(?:while|if|for)\M\s*...} ...
非常困难的部分是在括号中匹配部分。问题在于,这实际上是一种“语言”(在理论意义上),需要一种不同于正则表达式的解析器才能匹配(即递归下降解析器,其具有比使用的有限自动机更复杂的状态模型。 RE匹配)。更重要的是,在这些表达式中使用()
个字符很常见。最简单的方法是匹配在行尾的紧密括号,可能后面跟一个分号,但这绝对不正确。或者,也可以支持有限数量的嵌套parens。
# Match a few levels...
regexp {\m(?:while|if|for)\M\s*\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\)} ...
所以,让我们打破RE:
\m Word start (?:while|if|for) One of the keywords \M Word end \s* Optional spaces \( Open paren (?: Either... [^()] Non-paren... | Or... \( Open paren (?: Either... [^()] Non-paren... | Or... \( Open paren [^()]* Non-parens \) Close paren )* ... as many of the above as needed \) Close paren )* ... as many of the above as needed \) Close paren
如果你看一下上面的内容,你会发现一个模式。是的,你可以继续筑巢,做到你想要的深度。 无法做的是让RE引擎为你做嵌套。
答案 1 :(得分:0)
在你的正则表达式中,你正在使用\ s +。这意味着必须至少有一个空格/制表符/换行符。使用\ s *(0或更多空格)并为之前的内容添加逻辑:
if { [ regexp {(^|[ \t])(for|while|if)(\s*)(\()} $lineValue ] } {