如果Pattern在第1行匹配,我需要删除第4行

时间:2015-01-28 15:06:27

标签: regex perl vim sed

我需要一些正则表达式模式匹配的帮助并替换

我通常使用%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行 请详细说明如何实现这个目标

3 个答案:

答案 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命令。