我需要替换以下字符串:
<book name=""
author="">
到
<magazine>
我的代码不起作用:
sub substitution
{
my $find = "book name\=\"\"\nauthor\=\"\"";
my $replace = "magazine";
{
local @ARGV = ("$_[0]");
local $^I = '.bac';
while( <> )
{
if( s/$find/$replace/ig ) {
print;
}
else {
print;
}
} //while
}
答案 0 :(得分:3)
就像Brian已经说过的那样,使用XML解析器。下面是一个使用XML :: LibXML并使用setNodeName(用于更改元素名称)和removeAttributes(用于删除这两个属性)进行DOM操作的示例:
use strict;
use XML::LibXML;
my $doc = XML::LibXML->new->parse_string(<<EOF);
<books>
<book name=""
author="">
<chapter>something</chapter>
</book>
<book name=""
author="">
<chapter>something</chapter>
</book>
</books>
EOF
for my $book_node ($doc->findnodes('//book')) {
$book_node->setNodeName('magazine');
$book_node->removeAttribute($_) for qw(name author);
}
print $doc->serialize;
另一种可能性是在这里使用xslt ......
答案 1 :(得分:1)
我强烈建议您使用XML parser而非正则表达式well-documented reasons。
查看Comprehensive Perl Archive Network以获取更合适的库。
答案 2 :(得分:1)
如果您想要快速简便的解决方案(为什么还要使用Perl?),那么只需使用
my $find = qr|<book name=""\s+author="">|s;
my $replace = '<magazine>';
因为你想要在多行中替换某些东西,你不能逐行读取,而应该在标量中篡改文件(如果你的文件足够小以适应内存)
local $/; # undefines input lines separator
# open your file with open(FILE, '<', $filename);
my $text = <FILE>;
$text =~ s/$find/$replace/g;
# do with $text what you want now, print it or anything
# don't forget to close your FILE
这很快,很脏,但效果很好。如果您的文件不适合内存,或者您想确保一切正常,请使用XML解析器,但请记住
答案 3 :(得分:1)
使用xsh,XML::LibXML的包装:
open file.xml ;
for //book[@name="" and @author=""] {
rename magazine . ;
delete @* ;
}
save :b ;