简单的字符串替换不起作用

时间:2013-03-13 03:37:01

标签: string perl substitution

以下是我的代码:

my $string1 = '<td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td>';
my $string2 = 'http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3';


print "Before string substitution:\n$string1\n";
$string1 =~ s/$string2//;
print "After string substitution:\n$string1\n"; 

实际输出:

Before string substitution:
<td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td>
After string substitution:
<td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td> 

我的期望:

Before string substitution:
<td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td>
After string substitution:
<td><a href="">abcdefg</a><br />(123456)</td> 

有人可以告诉我我的代码有什么问题吗?

感谢。

2 个答案:

答案 0 :(得分:2)

可以通过在脚本中添加两个字符来解决该问题。你需要的是转义$string2中的元字符:

$string1 =~ s/\Q$string2//;

导致匹配失败的字符是问号?,此处未转义...aspx?...表示“匹配字符'x'的0或1”。字符.是与换行符匹配的通配符,这可能会导致误报。斜杠/由于是替换运算符s///的分隔符而是元字符,因此它们不需要进行转义,因为它们嵌入在字符串中。

使用\Q ... \E转义序列,正则表达式内部或quotemeta最容易转义元字符。

尝试手动转义这些类型的字符串并不是一个好主意,特别是如果文字匹配都是必需的。

答案 1 :(得分:1)

由于你要使用perl regex输入被认为是特殊字符的字符,你必须将它们转义为:

my $string2 = 'http:\/\/www\.aaa\.com\/downloads\/details\.aspx\?FamilyID=a1b2c3';

然后在运行程序时会显示预期的输出:

<td><a href="http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3">abcdefg</a><br />(123456)</td>
After string substitution:
<td><a href="">abcdefg</a><br />(123456)</td>

要从字符串中转义这些字符,最好只使用perl的quotemeta函数:

my $string2 = quotemeta('http://www.aaa.com/downloads/details.aspx?FamilyID=a1b2c3');

这将为您逃避特殊字符,然后您的正则表达式替换将正常工作。

修改

由于你因为没有转义的正则表达式字符而遇到问题,这个解决方案可能更简单,因为它不需要你转义任何字符:

substr($string1, index($string1,$string2), length($string2)) = '';

这是基于这个例子:

my $name = 'fred';
substr($name, 4) = 'dy'; # $name is now 'freddy'

substr的perldoc中找到。