in reply to Re: Regex (?{ code }) and use re 'eval'
in thread Regex (?{ code }) and use re 'eval'

Sorry, maybe this will help you out.

i want to take a hash of simple regex ie(0-9, a-z) and match them in square brackets/box brackets: /\[([0-9]+)\]/;
The matched value in the brackets then gets checked from a sub(to make it simple i have it go though the sub) and if the sub returns something it uses the value the sub returned and if the sub did not return anything it keep the data as it was

Replies are listed 'Best First'.
Re^3: Regex (?{ code }) and use re 'eval' (KISS)
by tye (Sage) on Nov 21, 2007 at 19:31 UTC

    I won't claim to clearly understand what you are doing but it looks like using (?{...}) is an overly complex way to go here. Something much simpler might work for you:

    s/(...)/ func( $1 ) || $1 /ge; s/(\[(...)\])/ func( $2 ) || $1 /ge; s/(\[(...)\])/ my $ret= func( $2 ); defined $ret ? "[$ret]" : $1 /ge; s/(\[(...)\])/ my @ret= func( $2 ); @ret ? "[@ret]" : $1; /ge;

    - tye        

      Simple is better ^^
      I like the examles and will be playing with them.

      Thanks ^^
Re^3: Regex (?{ code }) and use re 'eval'
by mwah (Hermit) on Nov 21, 2007 at 19:20 UTC
    i want to take a hash of simple regex ie(0-9, a-z) and match them in square brackets/box brackets

    Under these conditions, your "example 6" would look sth. like:

    use strict; use warnings; my %Build = ( jj => '0-9', kk => 'a-z', ); my $message = '[445] [5353453] [fff] [445]'; my $message6 = $message; while( my ($k,$v) = each %Build) { my %speed_fix; if(my @re_match = $message6 =~ m{ (?<=\[) [$v]+ (?=\]) }xisg ) { foreach my $m_check (@re_match) { next if $speed_fix{$m_check}; if( my $built = return_number($m_check) ) { $message6 =~ s{ \[ $m_check \] }{$built}xisg; ++$speed_fix{$m_check}; } } } } print "$message6\n"; sub return_number { my $numbers = shift; return $numbers; }

    Maybe one could delete more stuff - if you could provide an exact specification of the problem.

    Regards

    mwa

      it looks nice, but i do not know what you meant by "sth."
      The problem i found in the example 6 was when the "@re_match" is made it can have repeated values(thats why i have a check to see if its been used) and kinda seemed to me that it could take up to much resources if I used a larger message.
        sth. = something
Re^3: Regex (?{ code }) and use re 'eval'
by ikegami (Patriarch) on Nov 21, 2007 at 19:53 UTC

    What do you mean by "returns something"? I'm going to assume you mean "returns something defined". Adjust as needed.

    foreach my $range (values %Build) { $message =~ s{ (\[ ([$range]+) \]) }{ my $val = return_number("$2"); defined($val) ? $val : $1 }exig }

    If return_number is costly, you can memoize the returned value.

    my %memoize; foreach my $range (values %Build) { $message =~ s{ (\[ ([$range]+) \]) }{ my $val = exists($memoize{$2}) ? $memoize{$2} : return_number("$ +2"); $memoize{$2} = $val; defined($val) ? $val : $1 }exig }

    Why is Build a hash instead of an array? You don't use the keys. Also, Build is not a particularly good name.

      You assumed right ^^. looks good and I will be playing with it.
      the function I'm using wont be costly and the hash key will be used in the final version. I wanted to keep it as simple as possible in my examples.

      My final code would look something like this.
      # Hash format: $Build_AUBBC{$name} = $pattern . '||' . $type . '|| +' . $fn; foreach my $b_key (keys %Build_AUBBC) { warn "ENTER foreach do_build_tag $self" if $DEBUG_AUBBC; my ($pattern, $type, $fn) = split (/\|\|/, $Build_AUBBC{$ +b_key}); $message =~ s/(\[$b_key\:\/\/([$pattern]+)\])/ my $ret = check_build_tag( $2 , $fn ) || ''; $ret ? $ret : $1; /exig if ($type eq 1); $message =~ s/(\[$b_key\]([$pattern]+)\[\/$b_key\])/ my $ret = check_build_tag( $2 , $fn ) || ''; $ret ? $ret : $1; /exig if ($type eq 2); }

      Thanks ^^