使用grep和正则表达式选择跨越多行的文本

时间:2011-08-28 18:48:47

标签: regex grep

我正在尝试将行与仅包含 minOccurs xs:element 标记匹配。如下所示,其中一些包含一行的搜索条件,其中一些跨越多行。有没有办法使用grep和正则表达式选择它们。

<xs:element name="shipto">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="address" type="xs:string"/>
      <xs:element name="city" minOccurs="1" type="xs:string"/>
      <xs:element name="country" 
               minOccurs="1" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

正确的输出应如下:

<xs:element name="city" minOccurs="1" type="xs:string"/>
<xs:element name="country" 
               minOccurs="1" type="xs:string"/>

2 个答案:

答案 0 :(得分:2)

我建议不要使用正则表达式解析XML。以强大的方式将标签与终端标签匹配太复杂了。

在Perl中使用XML :: XPath(Ubuntu包libxml-xpath-perl)有一个命令行工具“xpath”。例如:

xpath -e '//*[@minOccurs=1]' file.xml

输出

-- NODE --
<xs:element name="city" minOccurs="1" type="xs:string" />
-- NODE --
<xs:element name="country" minOccurs="1" type="xs:string" />

答案 1 :(得分:1)

假设格式良好的XML(即没有未转义的&gt;内部属性),那么你可以这样做:

<xs:element[^>]+?\sminOccurs\s*=[^>]+>

但是,我不确定这是否适用于grep,因为grep匹配单独的行,所以你可能需要编写一个perl脚本或其他东西来执行它。

(注意,如果你以某种方式拥有包含值sminOccurs=的属性,那么你需要变得更聪明,但由于这似乎是地址数据,我假设这不太可能,并且手动删除任何发生的事情都不会成为问题。)