Reputation: 215
I want to have the output of $var below to be John D
my $var = "John Doe";
I have tried
$var =~ s/(.+\b.).+\z],'\1.'//g;
Upvotes: 1
Views: 1398
Reputation: 57640
A simple regex that solves this problem is the substitution
s/^\w+\s+\K(\w).*/\U$1/s
What does this do?
^ \w+ \s+
matches a word at the beginning of the string, plus whitespace towards the next word\K
is the keep escape. It keeps the currently matched part outside of that substring that is considered “matched” by the regex engine. This avoids an extra capture group, and is practically a look-behind.(\w)
matches and captures one “word” character. This is the leading character of the second word in the string. .*
matches the rest of the string. I do this to overwrite any other names that may come: you stated that Lester del Ray
should be transformed to Lester D
, not Lester D Ray
as a solution with \w*
instead of the .*
part would have done. The /s
modifier is relevant for this, as it enables .
to match every character including newlines (who knows what's inside the string?).\U
modifier to uppercase the rest of the string, which consists of the value of the capture.Test:
$ perl -E'$_ = shift; s/^\w+\s+\K(\w).*/\U$1/s; say' "Lester del Ray"
Lester D
$ perl -E'$_ = shift; s/^\w+\s+\K(\w).*/\U$1/s; say' "John Doe"
John D
Upvotes: 0
Reputation: 31
Here's a general solution (feel free to swap in '\w' where I used '.', and add a \s where I used \s+)
my $var = "John Doe";
(my $fname, my $linitial) = $var =~ /(.*)\s+(.).*/
Then you have the values
$fname = 'John';
$linitial = 'D';
and you can do:
print "$fname $linitial";
to get
"John D"
EDIT Until you do your next match, each of the capture parentheses creates a variable ($1 and $2, respectively), so the whole thing can be shortened a bit as follows:
my $var = "John Doe";
$var =~ /(.*)\s+(.).*/
print "$1 $2";
Upvotes: 3
Reputation: 1434
Assuming your string has ascii names this will work
$var =~ s/([a-zA-Z]+)\s([a-zA-Z]+)/$1." ".substr($2,0,1)/ge;
Upvotes: 0
Reputation: 126722
To replace the last sequence of non-whitespace characters with just the initial character, you could write this
use strict;
use warnings;
my $var = "John Doe";
$var =~ s/(\S)\S*\s*$/$1/;
print $var;
output
John D
Upvotes: 1
Reputation: 1941
Something like this might be a little more usable/reusable in the long run.
$initial = sub { return substr shift, 0, 1 ; };
make a get initial function
$var =~ s/(\w)\s+(\w)/&$initial($1) &$initial($2)/sge;
Then replace the first and second results using execute in the regex;
Upvotes: -1