perl 我如何引用特殊字符+和一个字母加两位数的字符串?

qf9go6mv  于 2023-05-01  发布在  Perl
关注(0)|答案(2)|浏览(168)

下面是我在Perl中修改的文本:

"tti_d01_DA_" + it + "H"

在我的替换文本中,我想用变量${Dom}替换d01,用${simul}替换DA,所以我有:

"tti_${Dom}_${simul}_" + it + "H"

我尝试了以下搜索原始字符串:

s/"tti_.\d{2}_\w+_" \+ \w+ \+ "H"/"tti_${Dom}_${simul}_" + it + "H"/;
s/"tti_(?=.*[a-z])(?=.*[0-9]) (?=.*[_]) \w+ (?=.*[_]) (?=.*["])\s(?=.*[+])\s\w+\s(?=.*[+])\s"H"/"tti_${Dom}_${simul}_" + it + "H"/;

我以为这是一个很简单的问题,但不知何故,我无法得到它。以上两个都没有找到我正在寻找的东西。

fzwojiic

fzwojiic1#

这在我的测试中有效

s/"tti_\K d[0-9]{2}_\w+_"(?= \+ it \+ "H")/\${Dom}_\${simul}_/

在原来的同一个字符串中,有DA模式,正如注解所说,可以改为NODA。这是由上面的\w+捕获的,在问题中尝试之后。然而,如果它只能是DANODA,就像注解所说的那样,那么人们可能想使用DA|NODA(而不是\w+),这样匹配就失败了。或者介于两者之间,比如[A-Z]+
这是一个取决于上下文的选择--要么使模式尽可能具有限制性,以防止意外(和不可接受)的输入,要么使其更宽松,以捕获更多可接受的内容。
这个问题并没有说明显示的attermps会发生什么,但这里有一些评论。
我很容易看到的唯一直接问题是替换端的$ s,如果它们要用作文字字符,则必须进行转义,否则它将查找变量$Dom$simul。†(但是strict不会让程序编译,因为没有这样的变量--你的程序中有use strict;吗?)
接下来,我使用\K lookhind,以便删除所有匹配到该点的内容(从$&保留在字符串中),并且不必在替换端重新输入。
同样,我使用(?=...)来查找需要替换的模式。这是一个 assertion(零长度),它不消耗任何东西,所以这些子模式也不需要替换到字符串中。
这两个调整'减轻'更换侧(但不是必要的)。
测试程序

use warnings;
use strict;
use feature 'say';

my $str = shift// q("tti_d01_DA_" + it + "H");
#say $str; 

$str =~ s/"tti_\Kd[0-9]{2}_\w+_"(?= \+ it \+ "H")/\${Dom}_\${simul}_/;

say $str;

†从注解中可以看出,问题可能与变量命名有关:程序中有数组@Dom@simul,需要替换为$Dom[index](等等)。
如果这确实是整个问题,那么在开始时使用use strict;就可以解决它。它甚至不会让程序编译,它会报告变量$Dom不存在。
拥有use strict;use warnings;是直接有帮助的,我想说是非常必要的。难怪许多工具都默认启用了它们,最后,在较新的Perl中也是如此。

plicqrtu

plicqrtu2#

您使用的regexp模式是正确的。
然而,$在双引号字符串中是特殊的,它包括s///的第二部分。逃离他们。
请始终使用use strict; use warnings;或等效程序,因为它会捕获此错误!
换句话说,你需要做的就是替换

s/"tti_.\d{2}_\w+_" \+ \w+ \+ "H"/"tti_${Dom}_${simul}_" + it + "H"/;

s/"tti_.\d{2}_\w+_" \+ \w+ \+ "H"/"tti_\${Dom}_\${simul}_" + it + "H"/;

演示:

$ perl -Mv5.10 -we'
   $_ = q{"tti_d01_DA_" + it + "H"};
   s/"tti_.\d{2}_\w+_" \+ \w+ \+ "H"/"tti_\${Dom}_\${simul}_" + it + "H"/;
   say;
'
"tti_${Dom}_${simul}_" + it + "H"

相关问题