http://www.perlmonks.org?node_id=1227620


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:  <%-{-{-{-<