我正在学习 Perl,并陷入了 s///运算符的评估中。 我尝试将“hello world”更改为“world,hello”,将“Hello world”更改为“World,hello”,即即使在使用 s///和/e 或/更改单词位置后,也保留字符串中的第一个标题大写字母(如果有) ee 选项。这是我的代码
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: ,
问题出在哪里?
最佳答案
问题是,当您执行正则表达式匹配 m//
时,您会丢失 $1
和 $2
的原始值。您可以通过将它们存储到临时变量来解决这个问题:
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
使第一个捕获组(“hello”)小写:
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
关于regex - 使用 s///e 进行评估,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25470851/