Regular Expression Problem

what regex to get all matches:

IF(.....);

I need to get the beginning and end of the previous line: the content can be as (well ), and then it can be different (... IF (...) ....) I need ONLY the content inside IF . Any idea?

This is because I need to get the Excel formula (if condition) and convert it to another language (java script).

EDIT:
I tried

       `/IF\s*(\(\s*.+?\s*\))/i or /IF(\(.+?\))/`

this does not work because it only matches if in 'IF(...)'

no )or(
+3
source share
5 answers

, problewm, . ( ), , . .

():

Find "IF"
Ensure next character is "("
Initialise counter parendepth to 1
While parendepth > 0:
  place next character in ch
  if ch == "(":
    parendepth += 1
  if ch == ")":
    parendepth -= 1

" " " ", .

+3

Perl. , .
, (. ) , ,
.
, .

use strict;
use warnings;

##
 $/ = undef;
 my $str = <DATA>;
 my ($lvl, $keyword) = ( 0, '(?:IF|ELSIF)' ); # One or more keywords
                                              # (using 2 in this example)    
 my $kwrx = qr/
   (\b $keyword \s*)        #1  - keword capture group
   (                        #2  - recursion group
     \(      # literal '('
        (                   #3  - content capture group
          (?:
              (?>  [^()]+ )    # any non parenth char
            | (?2)             # or, recurse group 2
          )*
        )
     \)      # literal ')'
   )
 | ( (?:(?!\b $keyword \s*).)+ )   #4
 | ($keyword)                      #5
 /sx;

##
 print "\n$str\n- - -\n";
 findKeywords ( $str );
 exit 0;

##
sub findKeywords
{
  my ($str) = @_;
  while ($str =~ /$kwrx/g)
  {
    # Process keyword(s), recurse its contents

      if (defined $2) {
        print "${1}[";
        $lvl++;
        findKeywords ( $3 );
      }
    # Process non-keyword text

      elsif (defined $4) {
        print "$4";
      }
      elsif (defined $5) {
         print "$5";
      }
  }
  if ($lvl > 0) {
      print ']';
      $lvl--;
  }
}

__DATA__

  IF( some junk IF (inner meter(s)) )
  THEN {
    IF ( its in
         here
         ( IF (a=5)
           ELSIF
           ( b=5
             and IF( a=4 or
                     IF(its Monday) and there are
                     IF( ('lots') IF( ('of') IF( ('these') ) ) )
                   )
           )
         )
         then its ok
       ) 
    ELSIF ( or here() )
    ELSE (or nothing)
  } 

:

  IF( some junk IF (inner meter(s)) )
  THEN {
    IF ( its in
         here
         ( IF (a=5)
           ELSIF
           ( b=5
             and IF( a=4 or
                     IF(its Monday) and there are
                     IF( ('lots') IF( ('of') IF( ('these') ) ) )
                   )
           )
         )
         then its ok
       )
    ELSIF ( or here() )
    ELSE (or nothing)
  }

- - -

  IF[ some junk IF [inner meter(s)] ]
  THEN {
    IF [ its in
         here
         ( IF [a=5]
           ELSIF
           [ b=5
             and IF[ a=4 or
                     IF[its Monday] and there are
                     IF[ ('lots') IF[ ('of') IF[ ('these') ] ] ]
                   ]
           ]
         )
         then its ok
       ]
    ELSIF [ or here() ]
    ELSE (or nothing)
  }
+1

, , :

/IF(\(.+?\))/

, IF() ( ): , + ( ) * ( ):

/IF(\(.*?\))/

--- EDIT

( ),

 /IF(\(.*\))/

which will make the regex "not greedy" by deleting ?. Thus, it will correspond to the longest string. Sorry, I mistakenly assumed that you did not have any parentheses.

0
source

Expanding on Paolo's answer, you might also need to worry about spaces and case:

/IF\s*(\(\s*.+?\s*\))/i
0
source

It is not possible to use only regular expressions. If you use .NET or use it, you should learn Balanced Matching .

0
source

All Articles