search/replace values from an array...

Discussion in 'Perl Misc' started by Sandman, Aug 1, 2004.

  1. Sandman

    Sandman Guest

    Ok, so here is a snippet that shows what I want to do:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my $string = "Hello World!";

    my %array = (
    "Hello (.*?)!", "Goodbye, little #1#!"
    # search replace
    );
    foreach (keys %array){
    if ($string=~m/$_/i){
    # It matched!
    $array{$_}=~s/#(\d+)#/$$1/;
    # replace #1# with $1, #2# with $2...
    $string=~s/$_/$array{$_}/g;
    # replace the string;
    }
    }

    print $string;



    The wanted result is "Goodbye, little World!", fetching "World" from $1 of the
    match 4 lines up, but the error message is

    File "test.pl"; Line 14: Can't use string ("1") as a SCALAR ref
    while "strict refs" in use

    So how do I solve it?

    --
    Sandman[.net]
     
    Sandman, Aug 1, 2004
    #1
    1. Advertising

  2. Sandman

    nyana Guest

    I thought scalars that started with a number had to take numbers. Is your
    scalar taking text? Then it should start with a letter.

    "Variable names that begin with a digit can contain only digits, and
    variable names that begin with a character other than an alphanumeric or
    underscore can contain only that character." -- Perl in a Nutshell,
    Patwardwan et al.

    "Sandman" <> wrote in message
    news:...
    > Ok, so here is a snippet that shows what I want to do:
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my $string = "Hello World!";
    >
    > my %array = (
    > "Hello (.*?)!", "Goodbye, little #1#!"
    > # search replace
    > );
    > foreach (keys %array){
    > if ($string=~m/$_/i){
    > # It matched!
    > $array{$_}=~s/#(\d+)#/$$1/;
    > # replace #1# with $1, #2# with $2...
    > $string=~s/$_/$array{$_}/g;
    > # replace the string;
    > }
    > }
    >
    > print $string;
    >
    >
    >
    > The wanted result is "Goodbye, little World!", fetching "World" from $1 of

    the
    > match 4 lines up, but the error message is
    >
    > File "test.pl"; Line 14: Can't use string ("1") as a SCALAR ref
    > while "strict refs" in use
    >
    > So how do I solve it?
    >
    > --
    > Sandman[.net]
     
    nyana, Aug 1, 2004
    #2
    1. Advertising

  3. Sandman

    Anno Siegel Guest

    Sandman <> wrote in comp.lang.perl.misc:
    > Ok, so here is a snippet that shows what I want to do:
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my $string = "Hello World!";
    >
    > my %array = (
    > "Hello (.*?)!", "Goodbye, little #1#!"
    > # search replace
    > );
    > foreach (keys %array){
    > if ($string=~m/$_/i){
    > # It matched!
    > $array{$_}=~s/#(\d+)#/$$1/;

    ^^
    Is this line 14? "$$1" is a scalar dereference that would fail with
    something like your message below.

    Also, you're changing the association of pattern and replacement in %array
    here. That is not something you want to do, except if you plan to
    use %array only once.

    > # replace #1# with $1, #2# with $2...
    > $string=~s/$_/$array{$_}/g;
    > # replace the string;
    > }
    > }
    >
    > print $string;
    >
    >
    >
    > The wanted result is "Goodbye, little World!", fetching "World" from $1 of the
    > match 4 lines up, but the error message is
    >
    > File "test.pl"; Line 14: Can't use string ("1") as a SCALAR ref
    > while "strict refs" in use
    >
    > So how do I solve it?


    Here is one way. When you check each regex, build the replacement string
    from the subpatterns that are captured by the regex. You do this by
    (globally) replacing the markers "#1#", "#2#", etc. with the corresponding
    submatch. The replacement string is now ready to use in a simple
    substitution. For instance:

    my %tab = (
    'Hello (.*?)!' => 'Goodbye, little #1#...',
    'Welcome (.*?) and (.*?)!' => 'Farewell, honorable #2# and fair #1#!',
    );

    for ( "Welcome ladies and gentlemen!", "Hello World!" ) {
    my $string = $_; # make a copy we can change

    while ( my ( $search, $replace) = each %tab ) {
    # build ready-to-use replacement string from template
    my $n = 1; # submatch number
    for ( $string =~ /$search/ ) { # loop over submatches
    $replace =~ s/#$n#/$_/g, # substitute one submatch everywhere
    $n ++; # next submatch
    }
    last if $string =~ s/$search/$replace/;
    }
    print "$string\n";

    }

    The "last" in the while-loop ensures that at most one replacement is
    done. Since you are using a hash, the replacements are tried in a random
    sequence. It wouldn't make sense to try re-replacement on an already
    processed string unless you control the order of the tries.

    Anno
     
    Anno Siegel, Aug 1, 2004
    #3
  4. Sandman

    Matt Garrish Guest

    "nyana" <> wrote in message news:8yaPc.27887$mg6.18729@fed1read02...
    > I thought scalars that started with a number had to take numbers. Is your
    > scalar taking text? Then it should start with a letter.
    >
    > "Variable names that begin with a digit can contain only digits, and
    > variable names that begin with a character other than an alphanumeric or
    > underscore can contain only that character." -- Perl in a Nutshell,
    > Patwardwan et al.
    >


    I have to believe you've taken that completely out of context. Not having
    the book, I refer you to the perldata perldoc:

    <quote>
    Names that start with a digit may contain only more digits. Names that do
    not start with a letter, underscore, digit or a caret (i.e. a control
    character) are limited to one character, e.g., $% or $$. (Most of these one
    character names have a predefined significance to Perl. For instance, $$ is
    the current process id.)
    </quote>

    The variables $1, $2 ... are special match variables (i.e., they contain the
    text matched by a regex). You cannot create variable names that begin with a
    digit for this reason, and variables that begin with a digit can only
    contain more digits (for example, $4323 would contain the text matched in
    the four-thousand-three-hundered-and-twenty-third set of parens, regardless
    of how hideous a regex that might be : ). You seem to be mistaking Perl for
    a strongly typed language, which it's not. $1 can contain the string 'Hello
    World' just as easily as $var can contain the numeric value 12.

    I would suggest you reread the perldocs, starting with perldata and moving
    on to perlre and perlvar.

    Matt
     
    Matt Garrish, Aug 2, 2004
    #4
  5. Sandman

    Paul Lalli Guest

    On Sun, 1 Aug 2004, nyana wrote:

    > I thought scalars that started with a number had to take numbers. Is your
    > scalar taking text? Then it should start with a letter.
    >
    > "Variable names that begin with a digit can contain only digits, and
    > variable names that begin with a character other than an alphanumeric or
    > underscore can contain only that character." -- Perl in a Nutshell,
    > Patwardwan et al.


    You've misparsed this paragraph. It does not say that variables whose
    names start with digits can contain only digits, etc. It says that
    variable NAMES that start with digits can contain only digits. The
    contents of the variable has nothing at all to do with the name of the
    variable.

    Paul Lalli
     
    Paul Lalli, Aug 2, 2004
    #5
  6. Sandman

    Eric Bohlman Guest

    Jim Gibson <> wrote in
    news:020820041326456159%:

    > "Or else it doesn't, you know. The name of the song is called
    > 'Haddock's Eyes' ."
    >
    > "Oh, that's the name of the song, is it?" Alice said, trying to feel
    > interested.
    >
    > "No, you don't understand," the Knight said, looking a little vexed.
    > "That's what the name is called . The name really is 'The Aged Aged
    > Man' ."
    >
    > "Then I ought to have said 'That's what the song is called?'" Alice
    > corrected herself.
    >
    > "No, you oughtn't: that's quite another thing! The song is called
    > 'Ways and Means' : but that's only what it's called , you know!"
    >
    > "Well, what is the song, then?" said Alice, who was by this time
    > completely bewildered.
    >
    > "I was coming to that," the Knight said. "The song really is
    > 'A-sitting on a Gate' : and the tune's my own invention."


    I don't think you can fully appreciate this in all its profundity unless
    you have an assembler background.
     
    Eric Bohlman, Aug 3, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Abby Lee
    Replies:
    5
    Views:
    436
    Abby Lee
    Aug 2, 2004
  2. Adrienne Boswell

    Replace commas in values in an array

    Adrienne Boswell, Apr 5, 2007, in forum: ASP General
    Replies:
    12
    Views:
    503
  3. Sandman
    Replies:
    6
    Views:
    112
    Sandman
    Aug 2, 2004
  4. ebm

    search and replace on an array

    ebm, Jun 30, 2006, in forum: Perl Misc
    Replies:
    8
    Views:
    101
    Uri Guttman
    Jun 30, 2006
  5. Peter Hanke
    Replies:
    1
    Views:
    152
    Dr.Ruud
    Jan 6, 2008
Loading...

Share This Page