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

If the regex is built from untrusted input, the consider these words from Nicholas Clark (talking about another issue):

So it's not going to be an issue at all, unless your programmers are foolish enough to allow untrusted user input to be interpolated into regular expressions. In which case, you were already open to denial of service attacks from patterns that bust the C stack (fixed by Dave for 5.10) or take until the heat death of the universe to complete (inherently unfixable in a general purpose programming language)

If the regex is built from trusted input, then use re 'eval'; won't hurt.

would like to know how to do it another way(thats stable).

Do what? You didn't say what it's suppose to do. There's not a single comment that hints as to what it's suppose to do. Yet we're suppose to figure out what you want from complex code that "has a few strange bugs in it".

Replies are listed 'Best First'.
Re^2: Regex (?{ code }) and use re 'eval'
by SFLEX (Chaplain) on Nov 21, 2007 at 19:08 UTC
    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

      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 ^^
      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.

      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 ^^