I am trying to write a regexp to search for for/if/while keywords in a string as read from C++ source code file but exclude any words which include them like:
WhatifYes()
Whatfor()
Waitforwhile()
I have written my regexp like below:
if { [ regexp {(for|while|if)(\s+)(\()} $lineValue ] } {
But it is not picking up cases like:
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 );
Initially I thought cause my regexp is framed to be like:
if/for/while \s+ ( #space or multiple spaces
But I tried including spaces in above example :
while (( int x = 0 ) > 0 );
while (( int x = 0 ) > 0 )
if ( (int x = 9) > 0 )
if ( (int x = 9) > 0 );
Still the regexp is not working – please let me know what regexp I should use to capture them?
Part of your problem is easy to address, and part is very hard.
The easy part is ensuring that you’ve got a whole word: the
\mconstraint escape only matches at the start of a word, and the\Mconstraint escape matches at the end, so we can use:The very hard part is matching the part in parentheses. The problem is that that’s really a “language” (in a theoretical sense) that requires a different kind of parser than a regular expression to match (i.e., a recursive descent parser, which has a more complex state model than the finite automatons used in RE matching). What’s more, using
()characters in those expressions is common. The easiest approach is instead match against a close parenthesis that’s at the end of the line, possibly followed by a semicolon, but that’s definitely not properly correct. Alternatively, supporting a limited number of levels of nested parens is also possible.So, let’s break that RE down:
\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 parenIf you look at the above, you’ll notice a pattern. Yes, you can keep on nesting to do as deep as you want. What you can’t do is make the RE engine do that nesting for you.