Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Re: Search and replace regex, but only retain a portion of the string (updated x4)

by AnomalousMonk (Bishop)
on Dec 22, 2018 at 22:51 UTC ( #1227620=note: print w/replies, xml ) Need Help??

in reply to Search and replace regex, but only retain a portion of the string

I think I even want to get to UK_Mobile_Vodafone_GBRVF.

Assuming that's really what you want:

c:\@Work\Perl\monks>perl -wMstrict -le "use constant T => q{UK Mobile - Vodafone [GBRVF] [MSRN]}; ;; my $dest = T; $dest =~ s{ \] \s+ \S+ \z }{}xms; print qq{2 steps: a: '$dest'}; ;; $dest =~ s{ \W+ }{_}xmsg; print qq{2 steps: b: '$dest'}; ;; $dest = T; ;; $dest =~ s{ \W+ (\w+ \] \z)? }{ $1 ? '' : '_' }xmsge; print qq{1 step: '$dest'}; " 2 steps: a: 'UK Mobile - Vodafone [GBRVF' 2 steps: b: 'UK_Mobile_Vodafone_GBRVF' 1 step: 'UK_Mobile_Vodafone_GBRVF'

Update 1: Or (with inspiration from tybalt89):
    $dest =~ s{ \W+ (\w+ \] \z)? }{ !$1 && '_' }xmsge;

Update 2: Or with no eval:

c:\@Work\Perl\monks>perl -wMstrict -le "my $dest = q{UK Mobile - Vodafone [GBRVF] [MSRN]}; ;; my @xlate = ('', '_'); ;; $dest =~ s{ \W+ (\w+ \] \z)? }{$xlate[! $1]}xmsg; print qq{'$dest'}; " 'UK_Mobile_Vodafone_GBRVF'
With Perl version 5.10+, you could use a persistent state variable:
    state $xlate = [ '', '_' ];
(changing the replacement expression, of course).
(The original code of this update had a  no warnings 'uninitialized'; statement which turned out to be unneeded. Removed.)

Update 3: Or another two-stepper:

c:\@Work\Perl\monks>perl -wMstrict -le "my $dest = q{UK Mobile - Vodafone [GBRVF] [MSRN]}; ;; $dest =~ tr{A-Za-z}{_}cs; $dest =~ s{ _ [^_]+ _ \z }{}xms; ;; print qq{'$dest'}; " 'UK_Mobile_Vodafone_GBRVF'

Update 4: Or:

c:\@Work\Perl\monks>perl -wMstrict -le "my $dest = q{UK Mobile - Vodafone [GBRVF] [MSRN]}; $dest =~ s{ \W+ (\w+ \] \z)? }{ [ '', '_' ]->[! $1] }xmsge; print qq{'$dest'}; " 'UK_Mobile_Vodafone_GBRVF'
I'm going to bed now. (Update: I don't know why I based this solution on an anonymous array;  ('', '_')[! $1] is a bit less obscure and probably slightly faster. But beyond that, this eval-ed solution doesn't really offer anything more than the ternary expression used in the eval one-step in my original reply. Well, it was late...)

Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re^2: Search and replace regex, but only retain a portion of the string (updated x4)
by ghenry (Vicar) on Dec 23, 2018 at 13:42 UTC

    Thanks. Amazing effort. Always stunned when someone spends a lot of time on these.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1227620]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2020-08-06 13:24 GMT
Find Nodes?
    Voting Booth?
    Which rocket would you take to Mars?

    Results (39 votes). Check out past polls.