使用s /// e评估

时间:2014-08-24 10:42:37

标签: regex perl eval substitution

我正在学习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: , 

问题出在哪里?

1 个答案:

答案 0 :(得分:2)

问题在于,当您执行正则表达式匹配$1时,您将失去$2m//的原始值。您可以通过将它们存储到临时变量来解决这个问题:

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