通过查找键从文件中删除多行

2024-03-29 11:32:48 发布

您现在位置:Python中文网/ 问答频道 /正文

假设文件中有以下行(不要将其视为XML文件):

<AVP code="123" name="abcd">
    <type>
        <high/>
    </type>
</AVP>
<AVP code="234" name="ukbkj">
    <type>
      <enum/>
    <type>
       <enum name="erdf"/>
 </AVP>

我想从(例如)AVP代码123中删除匹配的/AVP,以便删除AVP 123的所有数据。我怎样才能做到这一点? 下面是输出应该是什么样子。我想保存到一个文件,而不是打印到标准输出。你知道吗

<AVP code="234" name="ukbkj">
    <type>
       <enum/>
    <type>
       <enum name="erdf"/>
 </AVP>

Tags: 文件数据代码name标准typecodeenum
3条回答

通过perl。你知道吗

$ perl -0777pe 's/<AVP code="123".*?<\/AVP> *\n//sg' file
<AVP code="234" name="ukbkj">
<type>
<enum\>
<type>
<enum\>
<AVP code>

通过python。你知道吗

import re
with open('file') as f:
    m = f.read()
    splt = re.findall(r'(?s)<AVP\s+code="\d+".*?</AVP>', m)
    for i in splt:
        if '<AVP code="123"' not in i:
            print(i, end="")

如果您的输入将是XML,它将如下所示:

<?xml version="1.0"?>
<root>
    <AVP code="123" name="abcd">
        <type>
            <high/>
        </type>
    </AVP>
    <AVP code="234" name="ukbkj">
        <type>
          <enum/>
        </type>
        <type>
           <enum/>
        </type>
     </AVP>
</root>

您可以使用这个XSLT删除所有AVP元素。你知道吗

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:output omit-xml-declaration="no"/>

    <xsl:template match="node()|@*">
      <xsl:copy>
         <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="AVP[@code='123']" />
</xsl:stylesheet>

使用Python应用它:

import lxml.etree as ET

dom = ET.parse("avp.xml")
xslt = ET.parse("avp.xslt")
transform = ET.XSLT(xslt)
newdom = transform(dom)
with open("avp-out.xml", "wb") as o:
    o.write(ET.tostring(newdom, pretty_print=True))

输出在avp-out.xml

<root>

    <AVP code="234" name="ukbkj">
        <type>
          <enum/>
        </type>
        <type>
           <enum/>
        </type>
     </AVP>
</root>

更合适的方法是使用XML解析库,^{}是一个很好的方法。注意,您当前的示例是不是有效的XML:

use strict; 
use warnings; 

use XML::LibXML;

my $xml_filename = $ARGV[0];
die "Missing name of xml file to parse"
   unless $xml_filename;
open(my $xml_file, '<', $xml_filename) 
   or die "Error opening XML file: $!";

my $dom = XML::LibXML->load_xml(IO => $xml_file);
foreach my $node ( $dom->findnodes('/root/AVP') ) {
   $node->unbindNode()
      if $node->getAttribute('code') == 123;
}

open(my $out_fh, '>', "${xml_filename}.out") 
   or die "Unable to open outfile: $!";
binmode $out_fh;    

# write XML tree to file
$dom->toFH($out_fh);
close($out_fh);

相关问题 更多 >