Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

appending to end of string

by jc23 (Acolyte)
on Jun 25, 2003 at 21:31 UTC ( [id://269020]=perlquestion: print w/replies, xml ) Need Help??

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

I'm using the $' operator to append to a string that I find from using a search. For example given the string copyright 2003-2004, I want to append an additional year onto the end. So the resulting string would be copyright 2003-2004, 2005. I used s/copyright*/$& $' ,2005/g which does the job except somehow im getting the results of $' displayed twice. So in my example, after the substitution, i get copyright 2003-2004, 2005 2003-2004. Does anyone know how to fix this? Thanks.

Replies are listed 'Best First'.
Re: appending to end of string
by demerphq (Chancellor) on Jun 25, 2003 at 22:05 UTC

    I'm using the $' operator to append to a string that I find from using a search.

    Thats a variable actually.

    For example given the string copyright 2003-2004, I want to append an additional year onto the end.

    Use the concatenation (thats how comp sci people say "append to the end of a string" :-) operator the dot . so you might say

    use strict; use warnings; my $string="copyright 2003-2004"; my $year=2005; $string=$string.",".$year;

    But we normally wouldnt say that last line just like that, we would use a shortcut

    $string.=", $year";

    which does the same thing but is less chars to type ( $x .= $y is the same as $x= $x . $y) and we dont need to actually do concatenation here explicitly but out of lazyness we write it to use interpolation and then perl sort it out for us.

    I used s/copyright*/$& $' ,2005/g

    No-no-no-no. Thats a bit like using a flame thrower to light a candle. First off the special match variables $` $& and $' are bad to use in general (you can usually rewrite your regex to go without them), but to use them just to do concatenation wouldn't be done except in the wildest obfu/golf mutant code :-) Furthermore that regex says "match 'copyrigh' followed by 0 or more t's and then replace it with itself and everything to its right followed by ',2005'". So effectively we are inserting a copy of everything to after the word 'copyright' with itself follwed by ", 2005". '*' doesnt match any characters like it does on a command line. '*' itself is a qualifier that means "match the thing infront of me 0 or more times." We use the special character . (funny how that keeps coming up eh?) to represent any character (ahem, normally it means "every character but a newline"). So '.*' matches "zero or more of any characters but a newline". Which means that you could say s/(copyright.*)/$1, 2005/; and it would do what you want. But its unlikely anybody would do that. They would be much more likely to do s/(copyright 2003-2004)/copyright 2003-2005/; especially if the relevent string was embedded in a larger one.

    I really would recommend some doc time however. Its clear that you need a refresher in the basics.

    Good luck.


    ---
    demerphq

    <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
Re: appending to end of string
by arthas (Hermit) on Jun 25, 2003 at 21:50 UTC

    Hi!

    I hope I'm misunderstanding your problem. I think that, if you need to append a pre-known string such as 2005, you don't need to use s///, but just:

    $mystring .= ',2005';

    Michele.

Re: Using $'
by artist (Parson) on Jun 25, 2003 at 21:25 UTC
    You might want to read 'perldoc perlre' for the clear explaination of regular expressions and match variables.

    s/(copyright.*?)$/$1,2005/
    artist
      thanks.
        replace $1 with $& and it works. Thanks!
Re: appending to end of string
by antirice (Priest) on Jun 25, 2003 at 22:28 UTC

    I must recommend that you look at perlre and perlvar. Specifically the performance hit associated with $& (last match). Also, using $' (text following last match) operator in a substitution doesn't make sense at all (unless your intention is to have everything after copyright appear twice within the resulting string). If you are just dealing with a string that contains "copyright 2003-2004" then please take arthas's advice and get to know the concatenation (.) operator. If you are looking to add ",2005" to "copyright 2003-2004" within a larger string then a substitution is a good solution, but yours isn't at all what you're looking for. When your string is "this is copyright 2003-2004 etc." the results will be "this is copyright 2003-2004 etc. ,2005 2003-2004 etc." Instead, you should use backreferences to determine what you ought to be inserting. For instance:

    $_ = "I like the number 4 and I left my dog in the garage last night o +n accident"; # which I did...poor pup :-/ # store "number xx" where xx is a natural number as a # backreference and replace it with itself followed by # s/(?>number \d+)/ as well as the number 7/g; print $_,$/; __DATA__ output: I like the number 4 as well as the number 7 and I left my dog in the g +arage last night

    Hope this helps.

    UPDATED: Start to respond to a post that has one response that may be not what the OP is looking for, step away to get the dog out of the garage (again!), come back and finish the post, submit, and discover in your absence that two more replies have gone up :-/

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

Re: appending to end of string
by KPeter0314 (Deacon) on Jun 25, 2003 at 22:06 UTC
    What you probably want is something like s/copyright.*$/$&, 2005/g. I would really try to narrow the search string down some more though.

    Since you have "copyright*" as the match string, you are matching copyright or copyrightttt or copyrightttttt, but not "copyright 2003-2004" so the operator you are doing just leaves the rest of the string alone and only works with the part that matches. That is why you get the doubling up of 2003-2004.

    If you want to match "copyright 2003-2004" or basically copyright-to-the-end-of-the-line, then use "copyright.*$" to get it all. If not, then build a match that includes the numbers too. The dot-star bit is bad and should be eliminated. You should look at your data and build a better match. See Death to Dot Star! for more.

    Some of my details on the exact matching might be a little off, I'm still just a learner on regex's too.

    -Kurt

    Update: ++demerphq for an even better explanation.

      The dot-star bit is bad and should be eliminated.

      Bah. Thats cargo-cult if you ask me. Now if you said "dot-star on ocassion may not behave as you want it to so you should be careful using it" then I wouldn't say this. :-)

      The point is that you dont have to freak out just because you see a .* around. (I wonder how many there are in the standard modules? Hmmm) Do be careful, do read Death to Dot Star! (and advise other to do so as well,) do consider alternative before using it, but dont feel that you have to eliminate .* every time you see it.


      ---
      demerphq

      <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-03-29 06:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found