Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

replace all but first

by texuser74 (Monk)
on Sep 03, 2004 at 13:34 UTC ( [id://388270]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Perl experts,

the statement in my script
s/A/a/; replaces first occurance of A to a, and

s/A/a/g; replaces all occurance of A to a,

but i want to replace all the occurances except the first one.

please advise.

20040904 Edit by castaway: Changed title from 'regular exp.'

Replies are listed 'Best First'.
Re: replace all but first
by BrowserUk (Patriarch) on Sep 03, 2004 at 13:41 UTC
    my $s='aAaAaAaAaAaAAAAaaa'; substr( $s, 1+index( $s, 'A' ) ) =~ s[A][a]g; print $s; aAaaaaaaaaaaaaaaaa

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: replace all but first
by Roy Johnson (Monsignor) on Sep 03, 2004 at 14:30 UTC
    One way:
    /A/g; s/\G(.*?)A/$1a/g;
    Another way:
    s{(?<=A)(.*)}{my $rest=$1; $rest=~tr/A/a/; $rest}e;
    Without regex:
    substr($_, index($_, 'A')+1) =~ tr/A/a/;
    And, combining techniques:
    /A/g; substr($_, ++pos) =~ tr/A/a/;

    Caution: Contents may have been coded under pressure.
Re: replace all but first
by QM (Parson) on Sep 03, 2004 at 16:00 UTC
    I liked EdwardG's solution, but here's a less expert one:
    1 while s/^([^A]*A[^A]*)A/$1a/;

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Re: replace all but first
by terra incognita (Pilgrim) on Sep 03, 2004 at 16:46 UTC
    Here is my solution. It is no where as elegant and short as the previous ones. Comments on where I can improve this code and what practices I should stay away from are appreciated.
    use strict; #OPEN FILE A.txt for READING (CHECK FOR FAILURES) open (INFILE, "<","A.txt" ) or die "Could not open file A.txt: $!"; #OPEN FILE B.txt for WRITING (CHECK FOR FAILURES) open (OUTFILE, ">","B.txt" ) or die "Could not open file B.txt: $!"; my $prev_country = ""; my $line; my @myarray; my $country; my $company; while ($line = <INFILE>) { # SPLIT THE FILE BETWEEN COUNTRY AND COMPANY @myarray = split /></,$line; $country = $myarray[0]; # CHECK TO SEE IF THE CURRENT COUNTRY MATCHS THE PREVIOUS COUNTRY if ($prev_country ne $country) { #IF NEW COUNTRY PRINT WHOLE LINE print OUTFILE "$line"; $prev_country = ($country); next; } # IF SAME COUNTRY PRINT ONLY COMPANY $company = $myarray[1]; print OUTFILE "\t<$company"; } close OUTFILE; close INFILE;
      Not bad, but to keep it a little more re-usable and flexible (suppose, for instance, more tags/values are added later), you can do away with the $company and $country variables altogether, and do:

      ... @myarray = split /></,$line; if ( $prev ne $myarray[0] ) { $prev = $myarray[0]; } else { $myarray[0] = "<TAB"; } $line = join '><', @myarray; print OUTFILE, $line; ...
      This also takes care of the fact that I think the original author meant <TAB> literally. If I'm wrong, insert this after the join:

      $line =~ s/<TAB>/\t/;
Re: replace all but first
by DigitalKitty (Parson) on Sep 04, 2004 at 08:39 UTC
Re: replace all but first
by Grygonos (Chaplain) on Sep 03, 2004 at 13:43 UTC

    Firstly, there isn't much information you've given us. The layout of the file may be helpful. Secondly, I would reccomend using tr rather than s (see perlop). Since you are not replacing, but rather transliterating. However, if you wanted to replace a with ABBA (haha) then you would want to use the s operator.

      This is what i am trying to do

      my text file has
      <cnt>Germany</cnt><cmp>ALLIANZ INSURANCE</cmp>
      <cnt>Germany</cnt><cmp>ALLIANZ PARKWAY</cmp>
      <cnt>Germany</cnt><cmp>ALLIED DOMECQ</cmp>

      i want to replace it as
      <cnt>Germany</cnt><cmp>ALLIANZ INSURANCE</cmp>
      <TAB><cmp>ALLIANZ PARKWAY</cmp>
      <TAB><cmp>ALLIED DOMECQ</cmp>

      i.e. i want to replace "<cnt>Germany</cnt>" to "<TAB>" from its second occurance

        use strict; use warnings; my %seen; while ( <DATA> ) { next unless /^(<cnt>([^<]+)<\/cnt>)(.*)$/; print $seen{$2}++ ? "<TAB>$3\n" : "$1$3\n"; } __DATA__ <cnt>France</cnt><cmp>ACCOR</cmp> <cnt>France</cnt><cmp>AGF</cmp> <cnt>France</cnt><cmp>AIR LIQUIDE</cmp> <cnt>Germany</cnt><cmp>ALLIANZ INSURANCE</cmp> <cnt>Germany</cnt><cmp>ALLIANZ PARKWAY</cmp> <cnt>Germany</cnt><cmp>ALLIED DOMECQ</cmp> <cnt>United Kingdom</cnt><cmp>LEICESTER CITY FOOTBALL CLUB</cmp> <cnt>United Kingdom</cnt><cmp>SPENCER GEARS</cmp>
        If it's not going to appear twice on the same line:
        my $seen=0; while(<DATA>) { if ($seen) { s{<cnt>Germany</cnt>}{<TAB>} } else { $seen ||= m{<cnt>Germany</cnt>} } print; } __DATA__ <cnt>Germany</cnt><cmp>ALLIANZ INSURANCE</cmp> <cnt>Germany</cnt><cmp>ALLIANZ PARKWAY</cmp> <cnt>Germany</cnt><cmp>ALLIED DOMECQ</cmp>

        Caution: Contents may have been coded under pressure.
        $data =~ s{(<cnt>Germany</cnt>)}{$seen++?'<TAB>':$1}ge;

         

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-03-29 11:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found