【问题标题】:Perl regex matching: keywords may or may not existPerl 正则表达式匹配:关键字可能存在也可能不存在
【发布时间】:2017-08-04 06:13:15
【问题描述】:

我有如下字符串输入:

<Name>IncludeLeafPortfolios</Name><DataType>Boolean</DataType><Value>True</Value>
<Name>HierarchyDate</Name><DataType>Int</DataType><IsFixed>false</IsFixed>
<Name>HierarchyDate</Name><DataType>Int</DataType>
<Name>HierarchyDate</Name><DataType>Int</DataType><Value>0</Value><IsFixed>false</IsFixed>
<Name>HierarchyDate</Name><DataType>Int</DataType><Value>0</Value><IsFixed>false</IsFixed>

名称标签始终存在并且很有趣。 DataType 不感兴趣。 值标签和 IsFixed 标签可能存在也可能不存在。目标是捕获Value标签,如果其中一个存在或两者都存在,则IsFixed标签。

我的解决方案不起作用:

$element =~ m/^<Name>([\w\s]*)<\/Name>.*([<Value>[\w+\d+]<\/Value>]?)(<IsFixed>[\w+]<\/IsFixed>])?$

请提出建议。谢谢。

【问题讨论】:

  • 您可以检查其中是否至少存在一个,但如果两者都存在,则只能捕获其中一个。 if($element =~ m'.*|.*'i){} 如果你在 .* 周围加上括号,你只会得到第一个的值如果由于快捷方式评估两个标签都存在,则为一个。
  • 您确定这正是您的 XML 的外观吗?它看起来有点奇怪的结构。 (例如,我希望名称元素的“父”节点)。

标签: regex perl


【解决方案1】:

该数据看起来像 XML。使用 XML::LibXML 之类的库对其进行解析,然后对生成的结构执行操作。

不要使用正则表达式来处理 XML。 The results are just as bad as trying to use regular expressions for HTML.

【讨论】:

    【解决方案2】:

    XML 是上下文相关的。正则表达式不是。因此,您无法使用正则表达式可靠地解析 XML。

    所以使用解析器。我喜欢XML::Twig,它会有点像这样:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    use XML::Twig;
    use Data::Dumper;
    
    my $twig = XML::Twig -> new -> parsefile ( 'your_file.xml' );
    
    my @keys = qw ( Name Value IsFixed ); 
    
    my @rows; 
    my %current_row; 
    #iterate children
    foreach my $node ( $twig -> root -> children ) { 
       #extract tag and content
       my $tag = $node -> tag;
       my $content = $node -> text; 
       $current_row{$tag} = $content; 
       #if it's a name tag, assume it's a new row. 
       if ($tag eq 'Name' and %current_row) {
           push @rows, {%current_row};
           undef %current_row;
       }
    }
    #output results. 
    print join ",", @keys, "\n";
    foreach my $row ( @rows ) {
       print join ",", (map { $row -> {$_} // '' } @keys),"\n";
    }
    

    哪些输出:

    Name,Value,IsFixed,
    IncludeLeafPortfolios,,,
    HierarchyDate,True,,
    HierarchyDate,,false,
    HierarchyDate,,,
    HierarchyDate,0,false,
    

    不过,我会注意到您的 XML 很混乱 - 您确定它的结构是这样的吗?因为通常如果你有“关联”标签,那么它们会被分组在一个节点中。

    例如类似:

    <xml>
      <item>
         <Name>HierarchyDate</Name><DataType>Int</DataType><IsFixed>false</IsFixed>
      </item>
    </xml>
    

    这将大大简化问题,因为您可以:

    foreach my $item ( $twig -> root -> children ) {
       print join ",", (map { $item -> first_child_text($_) // '' } @keys),"\n"; 
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-15
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多