我是perl的新手,不知道如何实现以下目标。 我正在读取一个文件,并将这些行放在一个名为$ tline的变量中。接下来,我试图从$ tline中替换一些字符。 如果$ tline中有一些特殊字符,如(,?,=等),那么这个替换会失败。如何从这个变量$ tline中转义特殊字符?
if ($tline ne "") {
$tline =~ s/\//\%;
}
修改
对于这些混淆感到抱歉。这是我想要做的。
$tline =~ s/"\//"\<\%\=request\.getContextPath\(\)\%\>\//;
这适用于大多数情况。但是当输入文件有?在它里面,它失败了。
答案 0 :(得分:7)
怎么样:
$tline =~ s/\Q$var\E/;
这将导致quotemeta
应用于$var
的内容,该内容将被用作模式。
答案 1 :(得分:2)
这不是一个有效的正则表达式:
$tline =~ s/\//\%;
它被读取为perl
$tline =~ s/a/%;
a = /
您要做的是将正斜杠替换为您可能想要的百分号
$tline =~ s/\//%/;
哪种写得更好:
$tline =~ s,/,%,;
你可能还想要替换第一个正斜杠,所以你需要/g
标志:
$tline =~ s,/,%,g;
而且,这正是tr
(音译)的作用:
$tline =~ tr,/,%,;
更新我认为您想要的是一个简单的quotemeta()
,它接受您的输入,并且正则表达式转义元字符
$ perl -e'print quotemeta("</foo?>")'
\<\/foo\?\>
答案 2 :(得分:1)
您可以将所有特殊字符放在方括号(称为“字符类”)之间。以下内容将用百分号替换字符串中的所有左括号,问号和等号:
my $tline = 'fo(?=o';
$tline =~ s/[(?=]/%/g;
print "$tline\n";
打印:
fo%%%o
答案 3 :(得分:0)
嗯,一种方法是将所有要替换的字符放在方括号中。像这样:
$string =~ s/[,?=\/]//; # This will remove the first ',', '?', '=', or '/' from your string.
如果要删除所有'?'例如,在字符串中,在它的末尾使用g,如下所示:
$string =~ s/[?]//g;
我有点生疏,但我相信你只需要\或/前面的'\'(当然还有其他特殊字符,比如\ n,\ t等等)。像这样:
$string =~ s/[\\]/[\/]/g; # Switch from DOS to Unix delimiters.
$string =~ s/[\n\t]//g; # Remove all newlines and tabs
正如其他人所说,你发布的代码因为忘记了最后一个/而无法运行。这是将“奇怪”字符保留在一个盒子里的另一个好理由。
答案 4 :(得分:0)
quotemeta
是一个很好的函数,可以将带有特殊字符的精确文字转换为正则表达式。 \Q
and \E
是在正则表达式中做同样事情的好操作符。
但是,你的搜索表达并不复杂。在您的编辑中,您只是在寻找双引号和斜杠。事实上,我已经非常简化了表达式,因此它不包含单个反斜杠。因此quotemeta
也不是问题\Q
and \E
。
一旦减少,我在修改后的替换中没有看到任何会导致'?'问题的内容在$tline
。
简化的关键是'。','('和')'对表达式的替换部分没什么特别之处,所以这是等价的:
$tline =~ s/"\//"<%=request.getContextPath()%>\//;
更不用说更容易阅读了。当然这更容易:
$tline =~ s|"/|"<%=request.getContextPath()%>/|;
因为在Perl中,您可以使用s
operator选择所需的分隔符。
但是有了这些,这就有用了:
use Test::More tests => 1;
my $tline = '"/?"';
$tline =~ s|"/|"<%=request.getContextPath()%>/|;
ok( $tline =~ /getContextPath/ );
通过测试。也许你在一条线上有多个替换的问题。可以通过以下方式解决:
$tline =~ s|"/|"<%=request.getContextPath()%>/|g;
g是最后的全局开关,表示将此替换次数与输入中的次数相同。
然而,既然我可以看到你在做什么,我建议你更加严格地规范你要搜索的内容:
$tline =~ s~\b(href|link|src)="/~$1="<%=2request.getContextPath()%>/~g;
当我跑这个时:
use Test::More tests => 2;
my $tline = '"/?"';
$tline =~ s/"\//"<%=request.getContextPath()%>\//;
ok( $tline =~ /getContextPath/ );
$tline = 'src="/?/?/beer"';
ok( $tline =~ s~\b(href|link|src)="/~$1="<%=request.getContextPath()%>/~g
);
我获得了两次成功。
您的 true 问题尚未明确。