Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Pattern Substitution..

by slok (Acolyte)
on May 30, 2001 at 17:30 UTC ( [id://84242]=perlquestion: print w/replies, xml ) Need Help??

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

given following
=== $default_str = "good food"; $string1 = $default_string; $string2 = $default_string; $string3 = $default_string; $string1 =~ s/o*/e/; print $string1; $string2 =~ s/o+/e/; $string3 = ~ s/o/e/g; print $string1; print $string2; print $string3; ====
what I don't understand is why does pattern substitution for $string1 and $string2 does not gave me the end results of "geed feed" ?

Doesn't 1 and 2 look for "o".. and for 1, it has a "*", which means "match 0 or more", right?

and for 2, it has a "+", which means match 1 or more times, right?

thanks in advanced

Replies are listed 'Best First'.
Re: Pattern Substitution..
by arturo (Vicar) on May 30, 2001 at 17:39 UTC

    Remember that pattern matches, by default, are *greedy*, so they match the longest string that conforms to the pattern. And unless you specify 'g' on the end, they only match the first substring that matches the pattern you specify.

    So s/o*/e/ matches the first instance of "0 or more 'o's", and guess where that is? Right at the beginning of the string. When it says "match 0 or more", it means it =) So the result is "egood food".

    With your second example, it only matches the first substring that's one or more 'o's, (the 'oo' in "good"), and replaces that with a single 'e' => 'ged food'.

    HTH

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
Re: Pattern Substitution..
by davorg (Chancellor) on May 30, 2001 at 17:50 UTC

    There are a number of things going wrong here, not least of which is the fact that you are initialising $string1, $string2 and $string3 to an empty string - not what you think.

    use strict would have caught this error.

    But assuming that you do initialise all of your strings to "good food", the three results you get are "egood food", "ged food" and "geed feed" - which might also confuse you a bit. Let's look at the three regexes in a bit more detail.

    s/o*/e/ says "look for zero or more os and convert them to one e". The first place you find zero or more os is at the start of the string, so that is changed to an e.

    s/o+/e/ says "look for one or more os and convert them to one e". That finds the oo in "good" and converts them to an e.

    s/o/e/g says "find one o and convert it to an e, then repeat that process for every o in the string".

    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re: Pattern Substitution..
by Masem (Monsignor) on May 30, 2001 at 17:42 UTC
    You have the meanings right, but remember that whatever is matched on the left side of the s/// operator is completely replaced by the right hand side. Since perl's re engine is greedy, it will match as many o's in a row in the o+ case, and replace them all with a single e, or simply see no o's at the start of the string in the o* case, and put an e in front. You might try to have perl ignore greedy behavior with s/o*?/e/ and s/o+?/e/ and see what interesting results you get.

    Note that if all you are trying to do is replace one character with another, it's much easier to use tr than s. For example:

    $new_string = "good food"; $new_string =~ tr/od/ek/;
    (update not like this as japhy points out...
    $new_string = ( "good food" =~ tr/[od]/[ek]/; );
    ) will give you "geek feek", with 'o' converted to 'e', and 'd' converted to 'k'.


    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      No, it won't. tr/// in scalar context returns the number of characters translated; and the brackets are unnecessary. Not to mention, you're trying to modify a constant string. <code> ($new_string = "good food") =~ tr/od/ek/;

      japhy -- Perl and Regex Hacker
Re: Pattern Substitution..
by suaveant (Parson) on May 30, 2001 at 17:41 UTC
    ummm...

    $default_str = "good food";
    $string1 = $default_string;

    you need to use the same variable name ;) perl -w will help catch errors like that.

    Update arturo of course, is right too, dunno if your problem was the misspelling or if that just happened when you put the code on perlmonks
                    - Ant

Re: Pattern Substitution..
by Big Willy (Scribe) on May 30, 2001 at 22:30 UTC
    The * and the + swallow up all of the o's and replace them with a single e. This is called greediness, meaning that a pattern will match as much of a string as it can, maximizing the length of the pattern matched.

    If you want ungreedy operators that work in the opposite way, use *? and +?. In your simple situation, a e+? is as good as a plain old e, so it's not really necessary. The added ? becomes more useful with character sets like [aeiou] for example. You might also want to see the perl man page on regular expressions (perlre) for more info.
Re: Pattern Substitution..
by JP Sama (Hermit) on May 30, 2001 at 21:14 UTC
    I think you should do something like that:
    $string = qq{ what I don't understand is why does pattern substitution $string1 and $string2 does not gave me the end results of "geed feed" ? Doesn't 1 and 2 look for "o".. and for 1, it has a "*", which means "match 0 or more", right? and for 2, it has a "+", which means match 1 or more times, right? thanks in advanced }; $string =~ s/o/e/g; print $string;
    That should work... the last "g" is for GLOBAL.

    Regards!
    #!/jpsama/bin/perl -w
    $tks = `mount`;
    $jpsama = $! if $!;
    print $jpsama;
    

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://84242]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (3)
As of 2024-04-25 19:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found