Hello Perl Experts, I have a file that may have nested if statements. The form of the nested one looks like that: if { ... if { ... foo ... } else { ... foo ... } } The else clause is optional. One essential requirement is that I only find the ones which have the word "foo" inside the captured if statement. I wonder if there is a regular expression that can find and print the above pattern. Best Regards, Ahmed
![]() |
0 |
![]() |
a.h.osman@gmail.com writes: > I have a file that may have nested if statements. The form of the > nested one looks like that: > if { > ... > if { > ... foo ... > } > else { > ... foo ... > } > } This looks odd since there appears to be no test in the if, and the form of any test might alter the answer to your question. > The else clause is optional. > > One essential requirement is that I only find the ones which have the > word "foo" inside the captured if statement. > > I wonder if there is a regular expression that can find and print the > above pattern. Not a regular expression, no, because regular expressions can't match arbitrary nested structures like this, but Perl has extended regular expression that include a recursive construct that can match nested structures. However, it's tricky to get right and harder to maintain. It is very often best to find another solution. For example, if your file always has the line structure that you show, you can count the nesting and capture and report only the parts you need based on that running count. -- Ben.
![]() |
0 |
![]() |
On Sunday, November 20, 2016 at 9:53:01 PM UTC-8, a.h....@gmail.com wrote: > Hello Perl Experts, > > I have a file that may have nested if statements. The form of the nested one looks like that: > if { > ... > if { > ... foo ... > } > else { > ... foo ... > } > } > > The else clause is optional. > > One essential requirement is that I only find the ones which have the word "foo" inside the captured if statement. > > I wonder if there is a regular expression that can find and print the above pattern. > Assuming a recursive pattern will send you into the depths of despair as already mentioned, you could try a more fragile solution such as: # Deparse to clear comments and normalize the code, eg # perl -MO=Deparse someperl.pl. use feature 'say'; my $data = qx{ perl -MO=Deparse someperl.pl}; die $? if $?; my $pat = 'if|elsif|else'; while ( $data =~ m{ ( \s* (?:$pat) \s* .*? { .*?) (?=(?:$pat|}) ) }sgx ) { my $match = $1; say "match: $match\n" if $match =~ /foo/; }
![]() |
0 |
![]() |
On Monday, November 21, 2016 at 10:53:59 PM UTC-8, C.DeRykus wrote: > On Sunday, November 20, 2016 at 9:53:01 PM UTC-8, a.h....@gmail.com wrote: > > Hello Perl Experts, > > > > I have a file that may have nested if statements. The form of the nested one looks like that: > > if { > > ... > > if { > > ... foo ... > > } > > else { > > ... foo ... > > } > > } > > > > The else clause is optional. > > > > One essential requirement is that I only find the ones which have the word "foo" inside the captured if statement. > > > > I wonder if there is a regular expression that can find and print the above pattern. > > > > Assuming a recursive pattern will send you into the depths of despair > as already mentioned, you could try a more fragile solution such as: > > # Deparse to clear comments and normalize the code, eg > # perl -MO=Deparse someperl.pl. > > use feature 'say'; > > my $data = qx{ perl -MO=Deparse someperl.pl}; > die $? if $?; > > my $pat = 'if|elsif|else'; > while ( $data =~ m{ ( \s* (?:$pat) \s* .*? { .*?) (?=(?:$pat|}) ) }sgx ) { > my $match = $1; > say "match: $match\n" if $match =~ /foo/; > } Never mind... this is hopelessly beyond "fragile". You'll need a recursive regex but Deparse should help.
![]() |
0 |
![]() |