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.
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;
| [reply] [d/l] [select] |
|
it was that easy!.... thank you.
| [reply] |
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'
| [reply] [d/l] [select] |
|
Thank you for the code.
s{ _ (?= ^_* \z) }{,}xms;
I would appreciate if someone could explain what it's doing for each part.
| [reply] |
|
+----------------------------- 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'
| [reply] [d/l] [select] |
|
|
|
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.
| [reply] [d/l] [select] |
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. | [reply] [d/l] |
|
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?
| [reply] [d/l] [select] |
|
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.
| [reply] |
|
|
|
|