f



Finding nested patterns which has a word inside it

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
11/21/2016 5:52:54 AM
comp.lang.perl.misc 33233 articles. 2 followers. brian (1246) is leader. Post Follow

3 Replies
381 Views

Similar Articles

[PageSpeed] 47

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
Ben
11/21/2016 12:01:05 PM
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
C
11/22/2016 6:53:52 AM
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
C
11/22/2016 1:33:16 PM
Reply: