我想在一些模板文件中进行多行字符串替换,但保留一个漂亮的缩进。
这是模板的一个示例:
<TAG1>
<TAG2>
%REPLACETHIS%
</TAG2>
</TAG1>
现在,我只需将字符串%REPLACETHIS%替换为类似
的字符串<REPLACEDSTRINGTAG1>
replacedstringtext
</REPLACEDSTRINGTAG1>
它看起来像:
<TAG1>
<TAG2>
<REPLACEDSTRINGTAG1>
replacedstringtext
</REPLACEDSTRINGTAG1>
</TAG2>
</TAG1>
应该是这样的:
<TAG1>
<TAG2>
<REPLACEDSTRINGTAG1>
replacedstringtext
</REPLACEDSTRINGTAG1>
</TAG2>
</TAG1>
它变得更加复杂,因为模板将成为更大模板的一部分,它也应该正确缩进。
我试图在Perl中实现这一点,但基本上我所知道的所有语言中的问题都是一样的。
有没有人比通过跟踪当前缩进深度的变量逐行替换更好的想法?由于多级模板结构,这非常麻烦。
基本上,我需要的是一个简单的正则表达式的替代品,它不仅将替换字符串的第一行放在右列,而且将每一行放在该列上。因此,如果%REPLACETHIS%位于第10列,替换字符串中的所有行都应该放在第10列......也许在Perl中有一些带有正则表达式的棘手的内置魔法?
答案 0 :(得分:2)
现在您的模板文件是XML格式,您可以使用一些XML处理模块来处理它。它更灵活可靠。
对于您的情况,XML::LibXML可以完美处理:
use XML::LibXML;
use XML::LibXML::PrettyPrint;
my $xml = "template.xml";
my $parser = XML::LibXML->new();
my $tree = $parser->parse_file($xml);
my $root = $tree->getDocumentElement;
my ($replace_node) = $root->findnodes('/TAG1/TAG2');
$replace_node->removeChildNodes();
my $new_node = $tree->createElement('REPLACEDSTRINGTAG1');
$new_node->appendText('replacedstringtext');
$replace_node->addChild($new_node);
my $pp = XML::LibXML::PrettyPrint->new(indent_string => "\t");
$pp->pretty_print($tree);
print $tree->toString;
答案 1 :(得分:1)
不相信正则表达式是正确的方法,但如果您使用组来捕获%REPLACETHIS%
之前的缩进,则可以将其输入到替换中。
e.g。
s/(.*)%REPLACTHIS%/$1<REPLACEDSTRINGTAG1>\n$1 replacedstringtext\n$1</REPLACEDSTRINGTAG1>