我想让下面 $var 的输出成为 John D
my $var = "John Doe";
我努力了
$var =~ s/(.+\b.).+\z],'\1.'//g;
这是一个通用的解决方案(请随意在我使用 '.' 的地方交换 '\w',并在我使用 \s+ 的地方添加一个 \s)
my $var = "John Doe";
(my $fname, my $linitial) = $var =~ /(.*)\s+(.).*/
然后你有价值观
$fname = 'John';
$linitial = 'D';
你可以这样做:
print "$fname $linitial";
要得到
"John D"
编辑在您进行下一场比赛之前,每个捕获括号都会创建一个变量(分别为 $1 和 $2),因此可以将整个内容缩短如下:
my $var = "John Doe";
$var =~ /(.*)\s+(.).*/
print "$1 $2";
要仅用初始字符替换最后一个非空白字符序列,您可以这样写
use strict;
use warnings;
my $var = "John Doe";
$var =~ s/(\S)\S*\s*$/$1/;
print $var;
输出
John D
假设您的字符串具有 ascii 名称,这将起作用
$var =~ s/([a-zA-Z]+)\s([a-zA-Z]+)/$1." ".substr($2,0,1)/ge;
解决这个问题的一个简单的正则表达式是替换
s/^\w+\s+\K(\w).*/\U$1/s
这是做什么的?
^ \w+ \s+
匹配字符串开头的单词,加上下一个单词的空格\K
是保持逃生。它将当前匹配的部分保留在正则表达式引擎认为“匹配”的子字符串之外。这避免了额外的捕获组,并且实际上是一个后视。(\w)
匹配并捕获一个“单词”字符。这是字符串中第二个单词的前导字符。.*
匹配字符串的其余部分。我这样做是为了覆盖可能出现的任何其他名称:您说Lester del Ray
应该将其转换为Lester D
,而不是Lester D Ray
作为解决方案,\w*
而不是使用.*
部分。修饰符与此/s
相关,因为它可以.
匹配每个字符,包括换行符(谁知道字符串中的内容?)。\U
修饰符将字符串的其余部分大写,其中包含捕获的值。测试:
$ 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
$var = "John Doe";
s/^(\w+)\s+(\w)/$1 \u$2/ for $var;
从长远来看,这样的东西可能会更有用/可重用。
$initial = sub { return substr shift, 0, 1 ; };
做一个获取初始函数
$var =~ s/(\w)\s+(\w)/&$initial($1) &$initial($2)/sge;
然后在正则表达式中使用execute替换第一个和第二个结果;