1

我想让下面 $var 的输出成为 John D

my $var = "John Doe";

我努力了 $var =~ s/(.+\b.).+\z],'\1.'//g;

4

6 回答 6

3

这是一个通用的解决方案(请随意在我使用 '.' 的地方交换 '\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";
于 2013-06-13T15:41:50.643 回答
1

要仅用初始字符替换最后一个非空白字符序列,您可以这样写

use strict;
use warnings;

my $var = "John Doe";

$var =~ s/(\S)\S*\s*$/$1/;

print $var;

输出

John D
于 2013-06-13T15:40:06.120 回答
0

假设您的字符串具有 ascii 名称,这将起作用

$var =~ s/([a-zA-Z]+)\s([a-zA-Z]+)/$1." ".substr($2,0,1)/ge;
于 2013-06-13T15:46:46.240 回答
0

解决这个问题的一个简单的正则表达式是替换

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
于 2013-06-14T07:41:21.460 回答
0
$var = "John Doe";
s/^(\w+)\s+(\w)/$1 \u$2/ for $var;
于 2013-06-14T06:26:08.657 回答
-1

从长远来看,这样的东西可能会更有用/可重用。

$initial = sub { return substr shift, 0, 1 ; };

做一个获取初始函数

$var =~ s/(\w)\s+(\w)/&$initial($1) &$initial($2)/sge;

然后在正则表达式中使用execute替换第一个和第二个结果;

于 2013-06-13T15:23:11.733 回答