perl 条件正则表达式检查

问题描述 投票:0回答:2
regex perl
2个回答
0
投票

使用正则表达式处理 XML 有很多陷阱。

也就是说,下面是一种快速而肮脏的方法。它使用多个零宽度前瞻断言

(?=...)
。第一个按照优先顺序寻找替代方案,首先命名,然后返回路径。他们使用特殊的哈希
%+
来获取命名捕获组中的值,例如
(?<revision>...)

我在上面提到了陷阱。例如,请注意带引号的恶作剧。

#! /usr/bin/env perl

use strict;
use warnings;

while (<>) {
  if (/(?=.*\b(?<name>name\s*=\s*["'].*?["'])|(?<path>path\s*=\s*["'].*?["']))
       (?=.*\b(?<revision>revision\s*=\s*["'].*?["']))/x)
  {
    if (exists $+{path} && exists $+{revision}) {
      print $+{path}, " , ", $+{revision}, "\n";
    }
    elsif (exists $+{name} && exists $+{revision}) {
      print $+{name}, " , ", $+{revision}, "\n";
    }
    else {
      chomp;
      warn "$_\n  - must have name or path and revision\n";
    }
  }
}

正确的方法是使用解析器。

#! /usr/bin/env perl

use strict;
use warnings;

use XML::LibXML;

while (<>) {
  my $dom = XML::LibXML::->load_xml(string => $_);
  foreach my $project ($dom->findnodes('/project | /Project')) {
    if (exists $project->{name} && exists $project->{revision}) {
      print qq[name="$project->{name}" , revision="$project->{revision}"\n];
    }
    elsif (exists $project->{path} && exists $project->{revision}) {
      print qq[name="$project->{path}" , revision="$project->{revision}"\n];
    }
    else {
      warn "$0: $ARGV:$.: must have name or path and revision attributes\n";
    }
  }
}

将任一程序保存到

namerev
,然后运行它

perl namerev input-file.xml

产生下面的输出。

name="kernel/lk" , revision="e48c9314142c2ae93619ccd14aba2bc975165ffd"
name="device/google/contexthub" , revision="c453c8b8fb25fb8e1c59e8288331a70dbff44061"

-1
投票

if ($row =~ m/name="(.+?)"\spath="(.+?)"\srevision="(.+?)"/g) { 打印“$1 $3 “;

test
}
enter code here
elsif ($row =~ m/name="(.+?)"\srevision="(.+?)"/g) {
test
打印“$1$2 ”; } }
test

© www.soinside.com 2019 - 2024. All rights reserved.