regex - 使用 s///e 进行评估

标签 regex perl eval substitution

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

相关文章:

使用 eval 的 Javascript 函数赋值

asp.net - 如何在代码隐藏中调用 Eval?

regex - 从命令响应中提取数据并将其存储在变量中

java - 分割字符串时如何识别转义字符

python - 在 Python 上捕获与正则表达式的匹配并将捕获的字符串值分配给变量

perl - Perl CGI 程序是否存在 HTML 联系表单的缓冲区溢出或脚本漏洞?

c# - 将 Eval ("bitValue") 转换为 Bool

javascript - 注册按钮 HTML CSS JavaScript

bash - AWK:像输入文件一样保持字段间距

shell - 如何在 Perl 命令中扩展 shell 变量