Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

string manipulation

by parsifal (Novice)
on Mar 29, 2001 at 22:39 UTC ( #68158=perlquestion: print w/replies, xml ) Need Help??
parsifal has asked for the wisdom of the Perl Monks concerning the following question:

I have a string and want to alter all the instances of a certain character within in it. Here is my feeble attempt:
$instring = "This-is-my-string";
$outstring = "";

for ($i=0; $i   length $instring; $i++)
  if ($instring[$i] ne "-")
    $outstring .= $instring[$i];

    # replace with a new character or substring
    $outstring .= "_"; 

print "$outstring";

The desired out put would be "This_is_my_string"

Replies are listed 'Best First'.
Re: string manipulation
by indigo (Scribe) on Mar 29, 2001 at 22:43 UTC
    ($outstring = $instring) =~ tr/-/_/;

    This might be a little better.

    The tr (translate) operator does exactly what you are asking for. man perlop for more info.

    Also, in Perl, strings and arrays are not interchangible. $string[2] does not get you the third letter of $ gets you the third element of the array @string, a different beast entirely.
      Ch. 15 in Learning Perl also gives a good explaination of transliteration.
(tye)Re: string manipulation
by tye (Sage) on Mar 29, 2001 at 23:35 UTC

    You are new to Perl. You will probably save yourself a ton of time if you start all of your scripts by turning on warnings and using strict. For example:

    #!/usr/bin/perl -w use strict;
    The path to perl might need to be adjusted if your copy of Perl wasn't "correctly" installed and on newer versions of Perl you can do use warnings instead.

    Try these on the above script and you might get a clue that in Perl strings are not arrays. (:

            - tye (but my friends call me "Tye")
Re: string manipulation
by Xxaxx (Monk) on Mar 30, 2001 at 00:57 UTC
    Apparently you are coming into the world of Perl from a background in another compiler. C is my guess.

    Definitely start using the '-w' and 'strict' as recommended by others. This will put you into a better development path earlier.

    And, forget just about everything you think you know about string manipulation. When it comes to string manipulation Perl is light-years ahead of anything else I've looked at. You will be much better off just forgetting the way you've done it before and look around at the amazing functions available in Perl.

    There are many excellent books. You'll see them in the "Reviews" node at the top of this page. I suppose my current favorite must book is "Programming Perl" by Larry Wall, Tom Christiansen and Jon Orwant. You'll see folks around here talking about "The Camel" or "Camel". This is that book. (It has a camel on the front cover.)

    Good lucking. You're going to fall in love with Perl.


Re: string manipulation
by tune (Curate) on Mar 29, 2001 at 22:44 UTC
    What about regular expressions?

    $instring = "This-is-my-string"; $outstring = $instring; $outstring =~ s/-/_/g; print $outstring;

    -- tune

      I You are looking to just replace a specific char with a different char then tr works and is more effcient This node shows a benchmark comparision of the two methods.

      UPDATE: As Xxaxx points out below my benchmark was bit off. I re-ran it using the actuall functions needed for this problem and got these results
      Benchmark: timing 500000 iterations of Method One TR, Method Two s... Method One TR: 2 wallclock secs ( 1.87 usr + 0.00 sys = 1.87 CPU) @ + 267379.68/s (n=500000) Method Two s: 5 wallclock secs ( 4.84 usr + 0.00 sys = 4.84 CPU) @ +103305.79/s (n=500000)

      For more details click these nodes and see the discussion.
        I recommend running the benchmark again using the actual functions.

        In your referenced benchmark you're comparing:

        $data =~ tr/a-z/A-Z/;
        $data =~ s/(A-Za-z+)/uc($1)/ge;

        The uc($1) is a little different than:
        $outstring =~ s/-/_/g;

        When I ran the actual benchmark I got the following results:

        Run 1: (n=5000000)
        Method One TR: 3 wallclock secs ( 3.00 usr + 0.00 sys = 3.00 CPU) @ 166666.67
        Method Two S: 3 wallclock secs ( 3.05 usr + 0.00 sys = 3.05 CPU) @ 163934.43

        Run 2: (n=5000000)
        Method One TR: 2 wallclock secs ( 2.96 usr + 0.00 sys = 2.96 CPU) @ 168918.92
        Method Two S: 3 wallclock secs ( 3.08 usr + 0.00 sys = 3.08 CPU) @ 162337.66

        Run 3: (n=5000000)
        Method One TR: 4 wallclock secs ( 2.97 usr + 0.00 sys = 2.97 CPU) @ 168350.17
        Method Two S: 3 wallclock secs ( 3.08 usr + 0.00 sys = 3.08 CPU) @ 162337.66

        Seems like they are pretty much equal. But, alas, I'm real new to this benchmark stuff and I could have some weird caching issue.

        Even so without the eval of uc($1) this is certainly no 17 to 1 ratio as the referenced benchmark shows.

        Hope this helps
        p.s. Thanks to Desdinova for introducing me to the world of benchmarks.

Re (tilly) 1: string manipulation
by tilly (Archbishop) on Mar 30, 2001 at 04:33 UTC

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2018-08-22 05:43 GMT
Find Nodes?
    Voting Booth?
    Asked to put a square peg in a round hole, I would:

    Results (204 votes). Check out past polls.