gpt4 book ai didi

regex - Perl:如何在正则表达式中使用字符串变量作为搜索模式和替换

转载 作者:行者123 更新时间:2023-12-04 06:55:08 26 4
gpt4 key购买 nike

我想在正则表达式中使用字符串变量进行搜索模式和替换。预期的输出是这样的,

$ perl -e '$a="abcdeabCde"; $a=~s/b(.)d/_$1$1_/g; print "$a\n"'
a_cc_ea_CC_e

但是当我将模式和替换移动到一个变量时, $1没有被评估。
$ perl -e '$a="abcdeabCde"; $p="b(.)d"; $r="_\$1\$1_"; $a=~s/$p/$r/g; print "$a\n"'
a_$1$1_ea_$1$1_e

当我使用“ee”修饰符时,它会出错。
$ perl -e '$a="abcdeabCde"; $p="b(.)d"; $r="_\$1\$1_"; $a=~s/$p/$r/gee; print "$a\n"'
Scalar found where operator expected at (eval 1) line 1, near "$1$1"
(Missing operator before $1?)
Bareword found where operator expected at (eval 1) line 1, near "$1_"
(Missing operator before _?)
Scalar found where operator expected at (eval 2) line 1, near "$1$1"
(Missing operator before $1?)
Bareword found where operator expected at (eval 2) line 1, near "$1_"
(Missing operator before _?)
aeae

我在这里想念什么?

编辑

两者 $p$r是我自己写的。我需要的是在不触及 perl 代码的情况下进行多个类似的正则表达式替换,所以 $p$r必须在单独的数据文件中。我希望这个文件可以在以后与 C++/python 代码一起使用。
以下是 $p 的一些示例和 $r .
^(.*\D)?((19|18|20)\d\d)年   $1$2<digits>年
^(.*\D)?(0\d)年 $1$2<digits>年
([TKZGD])(\d+)/(\d+)([^\d/]) $1$2<digits>$3<digits>$4
([^/TKZGD\d])(\d+)/(\d+)([^/\d]) $1$3分之$2$4

最佳答案

$p="b(.)d";你得到一个带有文字字符的字符串 b(.)d .通常,正则表达式模式不会保留在带引号的字符串中,并且在正则表达式中可能没有它们的预期含义。但是,请参阅最后的注释。

这是什么qr operator适用于:$p = qr/b(.)d/;将字符串形成为正则表达式。

至于更换零件和/ee ,问题是$r首先评估,以产生 _$1$1_ ,然后将其评估为代码。唉,这不是有效的 Perl 代码。 _是裸词甚至是 $1$1本身无效(例如,$1 . $1 会是)。
$r 提供的示例有 $N以各种方式与文本混合。解析它的一种方法是提取所有 $N并将所有其他内容放入一个列表中,该列表保持字符串中的顺序。然后,可以将其处理为有效代码的字符串。例如,我们需要

'$1_$2$3other'  -->  $1 . '_' . $2 . $3 . 'other'

这是可以评估的有效 Perl 代码。

打破这个的部分是由 split 帮助的在分隔符模式中捕获。
sub repl {
my ($r) = @_;

my @terms = grep { $_ } split /(\$\d)/, $r;

return join '.', map { /^\$/ ? $_ : q(') . $_ . q(') } @terms;
}

$var =~ s/$p/repl($r)/gee;

带捕获 /(...)/split的模式,分隔符作为列表的一部分返回。因此,这是从 $r 中提取的一组术语,它们要么是 $N或其他,按其原始顺序并保留所有内容(尾随空格除外)。这包括可能的(前导)空字符串,因此需要过滤掉这些字符串。

那么除 $N 之外的每个术语s 包裹在 '...' 中,所以当它们都由 . 加入时我们得到一个有效的 Perl 表达式,如上例所示。

然后 /ee将使此函数返回字符串(如上面),并将其评估为有效代码。

我们被告知使用 /ee 的安全性外部输入不是这里的问题。尽管如此,这还是要记住的。见 this post ,由 Håkon Hægland 提供在评论中。随着讨论,它还将我们引导至 String::Substitution .它的用法在 this post 中演示.解决此问题的另一种方法是使用 replace来自 Data::Munge

更多讨论 /eethis post ,有几个有用的答案。

使用注意事项 "b(.)d"对于正则表达式模式

在这种情况下,使用括号和点,它们的特殊含义得以保留。感谢 kangshiyin提前提及这一点,并致 Håkon Hægland断言它。然而,这是一种特殊情况。双引号字符串直接拒绝许多模式,因为已经完成了插值——例如, "\w"只是一个逃脱的 w (什么是无法识别的)。单引号应该有效,因为没有插值。尽管如此,用作正则表达式模式的字符串最好使用 qr 形成。 ,因为我们得到了一个真正的正则表达式。然后也可以使用所有修饰符。

关于regex - Perl:如何在正则表达式中使用字符串变量作为搜索模式和替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41280103/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com