我想在一些模板文件中进行多行字符串替换,但保留了一个漂亮的缩进。
下面是一个模板示例:
<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中的正则表达式有一些棘手的内置魔力?
现在您的模板文件是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;
不相信regex是正确的方法,但是,如果您使用组来捕获%REPLACETHIS%
之前的缩进,则可以将其输入回子教程中。
例如
s/(.*)%REPLACTHIS%/$1<REPLACEDSTRINGTAG1>n$1 replacedstringtextn$1</REPLACEDSTRINGTAG1>
演示