我正在学习Perl,并在s ///运算符中继续进行评估。 我试着改变“你好世界”#39;世界,你好'和“你好世界”#39; to to' World,hello',即使在使用带有/ e或/ ee选项的s ///更改单词放置后,仍然保留第一个标题字母(如果有的话)。这是我的代码
my @strs = (
"hello world",
"Hello world",
);
foreach (@strs) {
say 'ORIG: ', $_;
s< (hello) \h+ (world) >
< $_ = (( $1 =~ m[^\p{Lu}] ) ? qq[\u$2, \l$1] : qq[$2, $1]) >xie;
say 'EDIT: ', $_ . "\n";
}
如果我改变例如
s< (hello) \h+ (world) >
< $_ = (( $1 =~ m[^\p{Lu}] ) ? qq[\u$2, \l$1] : qq[$2, $1]) >xie;
到
s< (hello) \h+ (world) >
< $_ = (( $1 eq 'Hello' ) ? qq[\u$2, \l$1] : qq[$2, $1]) >xie;
它可以根据需要工作,但是使用m //它会产生下一个输出:
ORIG: hello world
EDIT: world, hello
ORIG: Hello world
Use of uninitialized value $2 in concatenation (.) or string at ./pl line 340, <> line 2.
Use of uninitialized value $1 in lcfirst at ./pl line 340, <> line 2.
EDIT: ,
问题出在哪里?
答案 0 :(得分:2)
问题在于,当您执行正则表达式匹配$1
时,您将失去$2
和m//
的原始值。您可以通过将它们存储到临时变量来解决这个问题:
s< (hello) \h+ (world) >
< my ($h,$w)=($1,$2); $_ = (( $1 =~ m[^\p{Lu}] ) ? qq[\u$w, \l$h] : qq[$w, $h]) >xie;
实际上,我认为您根本不需要使用e
修饰符。您的替换可能只是s/([Hh]ello) ([Ww]orld)/$2, \L$1/
。这使用捕获组交换单词的顺序和\L
以使第一个捕获的组(&#34; hello&#34;)小写:
use strict;
use warnings;
use feature 'say';
my @strs = ('hello world', 'Hello World');
map { s/([Hh]ello) ([Ww]orld)/$2, \L$1/; say } @strs;
如果您明确想要使用e
,您可以使用以下内容:
s/([Hh]ello) ([Ww]orld)/qq{$2, } . lc($1)/e
输出(使用任一方法):
world, hello
World, hello