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;
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;
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";
Assuming your string has ascii names this will work
$var =~ s/([a-zA-Z]+)\s([a-zA-Z]+)/$1." ".substr($2,0,1)/ge;
$var = "John Doe";
s/^(\w+)\s+(\w)/$1 \u$2/ for $var;
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
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;