用漂亮的缩进替换多行字符串



我想在一些模板文件中进行多行字符串替换,但保留了一个漂亮的缩进。

下面是一个模板示例:

<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>

演示

最新更新