Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

regex to rename last _ with ,

by Anonymous Monk
on Sep 11, 2014 at 13:01 UTC ( [id://1100291]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to rename the last _ with a , but not sure how to do that.
Here is what I have so far-

my @flist = qw' 1st-device-CA_Eth.0/1 2nd-device-TX_Gig.1/1 '; print "@flist\n"; for my $file (@flist) { $file =~ s{\_[^_]+$}{, }; print "$file\n"; }
Output:
1st-device-CA_Eth.0/1 2nd-device-TX_Gig.1/1 1st-device-CA, 2nd-device-TX,

Now, how do I get the rest of the info back after that (,)? Please help.

Replies are listed 'Best First'.
Re: regex to rename last _ with ,
by choroba (Cardinal) on Sep 11, 2014 at 13:07 UTC
    If you know how to replace the first underscore with a comma, just add reverse:
    $file = reverse $file; $file =~ s/_/,/; $file = reverse $file;

    To get back what's after the inserted comma, the following should work:

    $file =~ s/_([^_]*)/,$1/; my $rest = $1;
    لսႽ ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      it was that easy!.... thank you.
Re: regex to rename last _ with ,
by AnomalousMonk (Archbishop) on Sep 11, 2014 at 13:18 UTC

    Not sure just what you're doing since you don't post in  <code> ... </code> tags, but I think I would use a look-ahead:

    c:\@Work\Perl\monks>perl -wMstrict -le "my @flist = qw( 1st-device-CA_Eth.0/1 2nd-device_TX_Gig.1/1 3rd_device_MO_Gig.1/1 ); ;; for my $s (@flist) { print qq{'$s'}; $s =~ s{ _ (?= [^_]* \z) }{,}xms; print qq{'$s'}; print ''; } " '1st-device-CA_Eth.0/1' '1st-device-CA,Eth.0/1' '2nd-device_TX_Gig.1/1' '2nd-device_TX,Gig.1/1' '3rd_device_MO_Gig.1/1' '3rd_device_MO,Gig.1/1'

      Thank you for the code.

      s{ _ (?= ^_* \z) }{,}xms;

      I would appreciate if someone could explain what it's doing for each part.
        +----------------------------- In the scalar $s (interpreted as a str +ing), | +--------------------- if you find an _ (underscore) | | +----------------- that's followed by 0 or more of anythi +ng but an _ (underscore) | | | and then the end-of-string, | | | + -- replace it with a , (comma). | | | | V V V V $s =~ s{ _ (?= [^_]* \z) }{,}xms;

        Update: See "Look-Around Assertions" in the Extended Patterns of perlre.

        (And the use of  <code> ... </code> tags would still be much appreciated.)

        Another Update: If you have Perl version 5.10+, another way (see  \K in Extended Patterns):

        c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; my @flist = qw( 1st-device-CA_Eth.0/1 2nd-device_TX_Gig.1/1 3rd_device_MO_Gig.1/1 ); ;; for my $s (@flist) { print qq{'$s'}; $s =~ s{ .* \K _ }{,}xms; print qq{'$s'}; print ''; } " '1st-device-CA_Eth.0/1' '1st-device-CA,Eth.0/1' '2nd-device_TX_Gig.1/1' '2nd-device_TX,Gig.1/1' '3rd_device_MO_Gig.1/1' '3rd_device_MO,Gig.1/1'

Re: regex to rename last _ with ,
by Anonymous Monk on Sep 11, 2014 at 13:10 UTC

    Use () to catch the end portion: m{ _ ([^_]+) $ }x. Then use the portion captured in replacement via $1. And, RTFM.

Re: regex to rename last _ with ,
by dmitri (Priest) on Sep 13, 2014 at 16:14 UTC
    This can be done without advanced features like lookaheads:
    s/_([^_]*)$/,$1/
    I am not sure if I prefer this or reverse solutions. If strings are large and there are many underscores in a string, I'd use reverse.
      This can be done without advanced features like lookaheads ...

      It seems strange to me to see a regex lookahead (or, in general, a look-around) assertion described as 'advanced'. It's as if one had said "X can be done without advanced features like lexical variables or hard references." Present, I believe (although I haven't taken the trouble to confirm this), since version 5.0, this is a feature I consider part of the 'baseline' definition of Perl 5.

      Whenever I allude to a feature like the  \K regex operator or the defined-or operator, I feel obliged to mention that is is only available beginning with Perl version 5.whatever and I make an effort to highlight its presence in a code example by including a  use 5.x; statement at the beginning, but I always assume that Perl 5 is the baseline for discussion nowadays. (Does anyone use a version 4 interpreter anymore?)

      This is only idle curiosity, but can you say why you consider regex look-around assertions advanced?

        A couple of reasons. First, I can never remember the exact syntax of the look-around assertions, so I have to perldoc perlre each time I use one. This makes it advanced in my mind. I guess this is highly subjective, so your point is taken.

        Second, the more features are used in a regular expression, the more there is to translate when you want to use it in another tool. Doing without look-ahead brings the RE to a lower common denominator, so to speak.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (1)
As of 2024-04-24 14:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found