bfdi533 has asked for the wisdom of the Perl Monks concerning the following question:

I have a string (well, lots of them actually) that looks like this:
char(123)+char(107)+char(112)+char(43)

I need to be able to parse this out and eval the char(xxx) statements at the same time. I am at a total loss. I am sure it will take a regex of some sort to split that out but that is beyond my meager regex skills at the moment. And then I believe it will take an eval of some sort but again, that escapes me. I have been at this for some time now and think I have lost my perspective.

Alas but I have no working code of any sort ...

A fresh view from someone out there?

Update:

The string to parse actually looks like this with "stuff" before it and "stuff" after it since it is part of a SQL statement:

select char(123)+char(107)+char(112)+char(43) from table

Replies are listed 'Best First'.
Re: parsing and evaluating a string
by bobf (Monsignor) on Apr 24, 2006 at 05:46 UTC

    This does what I think you're asking, but without context I can't give you anything more.

    use strict; use warnings; my $string = 'char(123)+char(107)+char(112)+char(43)'; # change all 'char' to 'chr' (the Perl function) $string =~ s/char/chr/g; # split the string on '+', eval each part, then join the resulting # characters back into a single string $string = join( '', map { eval $_ } split( /\+/, $string ) ); print "$string"; # {kp+

    Please note that this is very simple code that makes a lot of assumptions. For example, will all of your strings be of the format described in the OP? Will there ever be any other functions besides chr? The eval could be risky - how much do you trust the source of the string?

    HTH

      Your assumtions are rather correct.

      All strings will be in this format except that they will have stuff before them and stuff behind them. This is actually embedded into a SQL select statement and needs to be evaluated to be able be read and/or parsed properly. For instance:

      select char(123)+char(107)+char(112)+char(43) from table

      No, there will not be any other functions and it can most definitely be trusted.

Re: parsing and evaluating a string
by davido (Cardinal) on Apr 24, 2006 at 05:42 UTC

    What is the correct sum of the following characters?

       {   123
       k   107
       p   112
       *    42
    +
    -----
     ???
    

    They don't really add in a numeric sense.

    What is the bigger picture here? What are you trying to accomplish?

    At least the parsing part shouldn't be too difficult:

    my $string = "char(123)+char(107)+char(112)+char(42)"; my @characters = map{ chr $_ } $string =~ m/(\d+)/g; print "$_\n" foreach @characters;

    Dave

      Sorry, should have been a bit more clear. The '+' is a concat operator not a sum operator.

        Maybe this then:

        use strict; use warnings; my $input = "char(123)+char(107)+char(112)+char(42)"; my $output .= chr( $_ ) foreach $input =~ m/(\d+)/g; print "$output\n";

        Dave

Re: parsing and evaluating a string
by johngg (Canon) on Apr 24, 2006 at 11:12 UTC
    Like bobf, I have assumed that + is a concatenation. I thought I'd have a try without using split or map. Here it is

    use strict; use warnings; my $str = "char(123)+char(107)+char(112)+char(43)"; my $newStr; () = $str =~ m|(\d+)(?{$newStr .= chr($1)})|g; print "$newStr\n";

    When run this produces

    {kp*

    Cheers,

    JohnGG

Re: parsing and evaluating a string
by Fletch (Bishop) on Apr 24, 2006 at 13:12 UTC

    Of course one could be lazy and simply use the database itself to compute the answer, sidestepping any issues of doing the parsing in Perl.

    my $expanded =$dbh->selectrow_array( qq{SELECT char(123)+...+char(43); +} );
Re: parsing and evaluating a string
by TedPride (Priest) on Apr 24, 2006 at 12:53 UTC
    Or:
    use strict; use warnings; my $str = 'char(123)+char(107)+char(112)+char(43)'; $str =~ tr/+/ /; $str =~ s/char\((\d+)\)/chr($1)/eg; print $str;
    I know I could have made this neater by using $_, but he probably has the value in some variable.
      The down side to your solution is that it introduces spaces (because of the tr/+/ /) into the string that weren't in the original chr(n1)+chr(n2)+... sequence. The solution is to change the substiution

      $str =~ s/char\((\d+)\) ?/chr($1)/eg;

      Cheers,

      JohnGG