using eval statement inside regexp :

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • zcabeli
    New Member
    • Jan 2008
    • 51

    using eval statement inside regexp :

    Hi, i'm looking for a way to use eval expression in perl regexp. for example. if i want to match the following pattern X_(X+1)_(X+2) using a single code line, where X represent a numeric value. i.e. 1_2_3 but not 1_2_2

    i'd like to know if the following pseudo code can be written in perl:

    Code:
    ([0-9]+)_eval(\1+1)_eval(\1+2)
    so far what i do is grouping the first numeral, and use it to create the consecutive numerals, and add them all to my regexp

    thanks alot
  • miller
    Recognized Expert Top Contributor
    • Oct 2006
    • 1086

    #2
    It might be possible to do something like that all in a regex, but it likely will be convoluted and hard to read code. I'd recommend that you simply match the basic part of the pattern, and then do the math to determine whether the numbers match your requirements.
    Code:
    #!/usr/bin/perl
    
    my $data = do {
    	local $/;
    	<DATA>
    };
    
    while ($data =~ m{(\d+)_(\d+)_(\d+)}g) {
    # while ($data =~ m{(\d+)(?=_(\d+)_(\d+))}g) {
    	if ($1 == $2 - 1 && $2 == $3 - 1) {
    		print "${1}_${2}_${3}\n";
    	}
    }
    
    1;
    
    __DATA__
    Hi, i'm looking for a way to use eval expression in perl regexp.
    for example. if i want to match the following pattern X_(X+1)_(X+2)
    using a single code line, where X represent a numeric value. i.e. 1_2_3 but
    not 1_2_2
    
    and or more testing
    1_4_5_6_7_3_6_7_8_12_13_3_4_5 6 7 8 9
    10asdfoiuasdfljkoiuasdf
    9_0_1-2_3_4_6
    You'll notice that I included two different regex's in the above code. If you use the current one, overlapping solutions will not be found like 4_5_6 and 5_6_7. If you want overlapping solutions to be found, you need to use the regex that is currently commented out instead.

    - Miller

    Comment

    • zcabeli
      New Member
      • Jan 2008
      • 51

      #3
      Hi Miller,

      many thanks for your comprehensive response, it's definitely more readable than what i did :-)

      Comment

      • miller
        Recognized Expert Top Contributor
        • Oct 2006
        • 1086

        #4
        I'd also like to point out that I missed the case where the pattern has extra numbers either immediately preceding or following the match. To solve that simple rely on the fact that the middle number has set boundaries, and match based off of that.
        Code:
        #!/usr/bin/perl
        
        my $data = do {
        	local $/;
        	<DATA>
        };
        
        while ($data =~ m{(\d+)(?=_(\d+)_(\d+))}g) {
        	my $match = ($2 - 1) . "_${2}_" . ($2 + 1);
        	if ("${1}_${2}_${3}" =~ /$match/) {
        		print $match . "\n";
        	}
        }
        
        #print $data;
        
        1;
        
        __DATA__
        Hi, i'm looking for a way to use eval expression in perl regexp.
        for example. if i want to match the following pattern X_(X+1)_(X+2)
        using a single code line, where X represent a numeric value. i.e. 1_2_3 but
        not 1_2_2
        
        and or more testing
          #_#_#_#   #_#_#       #_#_#
        1_4_5_6_7_3_6_7_8_12_13_3_4_5 6 7 8 9
        10asdfoiuasdfljkoiuasdf
              #_#_#
        9_0_1-2_3_4_6
        and what about 15_6_789

        Comment

        Working...