友
我需要一些正则表达式模式匹配的帮助并替换
我通常使用%s/findstring/replacestring/g
进行模式匹配,并在同一行中替换
但如果我的文件是这样的话
<tracker xid="tracker4795">
<title>MIC-DMI Change Requests</title>
<description>New tracker created </description>
<dateCreated>2010-05-03 15:18:10 EST</dateCreated>
<displayLines>1</displayLines>
<isRequired>false</isRequired>
我需要模式匹配<tracker xid.*>
并转义所有行,直到它再次与<displayLine.*>
匹配,如果这些符合我需要删除的模式
<isRequired>.*
如果在第4行和第6行匹配模式,则删除第7行 请详细说明如何实现这个目标
答案 0 :(得分:1)
您必须匹配整组线。为此,请注意.
不匹配换行符;必须通过\n
明确指定。有了它,您有多种选择:
模式更复杂,但这是一般方法:
:%s/\(<tracker xid=.*\n\%(.*\n\)\{3}<displayLines>.*\n\)<isRequired.*\n/\1/g
这只是通过:global
建立匹配,然后使用相对寻址来删除该行。
:g/<tracker xid=.*\n\%(.*\n\)\{3}<displayLines>.*/+5delete
只有在您完全确定XML源是一致的,众所周知的格式时才这样做。文本编辑器/正则表达式是一个快速而准备好的工具,但从根本上说是错误的工具。请注意这一点,并在出现问题时不要责怪该工具。 Read more here. 对于生产级可靠性和自动化,请使用XML工具(例如 XSL转换)。
答案 1 :(得分:0)
当你说“这样的事情”时。 看起来就像你在那里得到的那样是XML。我无法肯定地说,因为&#39;类似这样的事情&#39;涵盖了很多缺陷。
但是,如果是 XML,尝试使用正则表达式解析它是一个非常糟糕的主意。原因是XML是一种具有非常严格规范的定义数据格式。如果每个人都坚持这个规范,那么一切都很好,花花公子。
但是,如果某人假设,您将把他们的XML作为XML处理,而您不是(因为您正在使用正则表达式),您将要创建的是一段脆弱的代码,在未来的某个时刻将无缘无故地随机破解 - 因为他们坚持XML规范,但以完全有效的方式改变了一些东西。
因此,假设它是XML,并且看起来像&#39;下面的示例 - 我建议使用Perl和XML::Twig来解析您的数据。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $xml;
{ local $/; $xml = <DATA> };
my $data = XML::Twig->new( pretty_print => 'indented' )->parse($xml);
foreach my $element ( $data->root->children('tracker') ) {
my $xid = $element->att('xid');
print $xid, "\n";
foreach my $subelement ( $element->children ) {
if ( $subelement->name eq 'isRequired' ) {
#delete the 'isRequired' line
$subelement->delete;
}
}
}
$data->print;
__DATA__
<xml>
<tracker xid="tracker4795">
<title>MIC-DMI Change Requests</title>
<description>New tracker created </description>
<dateCreated>2010-05-03 15:18:10 EST</dateCreated>
<displayLines>1</displayLines>
<isRequired>false</isRequired>
</tracker>
</xml>
答案 2 :(得分:0)
如果您知道输入是示例格式(每行只有一个开放标记,并且所有跟踪器标记包含displaylines和isrequired标记),或者您可以强制它使用该格式,那么我认为搜索 - 和 - 替换是太笨重,完整的XML解析是“正确的”,但比你需要的更复杂,你应该尝试使用:g
命令更简单的方法:
:g#<tracker xid#/<displayLine/d
这只是搜索匹配“&lt; tracker xid”的行,然后在匹配“&lt; displayLine”之后删除下一行
因此,在“&lt; tracker”和“&lt; displayLine”之间不需要特定数量的行,因此它对行偏移的差异更加稳健,但格式化更改仍然非常脆弱。
然而,我重复其他人的警告:如果格式不容易且一致可预测,那么我建议在循环中逐行解析文件,或者使用真正的XML解析器(可能使用Vim的Perl或Python集成),而不是使用:s
或:g
命令。