使用正则表达式解析许可证文件



我想解析一个以某种方式包含此类内容的许可证文件。

组件="A0000 B0000 G0000">

文件中必须有引号,以标记包中组件的开始和结束。我已经在 regex101.com 上测试了组合,但这并不能解决问题

正则表达式("?(?<components>w+)*s?"?)适用于字符串"A0000 B0000 G0000",并向我返回我需要的组件的单个值:A0000、B0000 等

但是当我测试(COMPONENTS|PACKAGES)=("?(?<components>w+)s?"?)时,块无法返回这些值,只返回第一个 A0000。

我需要帮助提取所有这些单独的值。请帮忙。

由于我的解决方案对您有用,因此我发布了一个答案:

(?:G(?!^)s+|(?:COMPONENTS|PACKAGES)=")K[^s"]+

模式匹配:

  • (?:G(?!^)s+|(?:COMPONENTS|PACKAGES)=")- 两种选择之一:
  • G(?!^)s+- 前一场比赛的结束(G匹配行/字符串的开头或前一场比赛的结束,因此(?!^)"减去"字符串位置的开头)和 1+ 空格
  • |- 或
  • (?:COMPONENTS|PACKAGES)=-COMPONENTS=PACKAGES=
  • K- 匹配重置运算符(丢弃当前匹配的文本)
  • [^s"]+- 除空格和双引号以外的 1 个或多个字符。

我可能误解了问题,但是简单的呢

my %result;
while (<$fh>) {
my ($type, $components) = /(w+)s*=s*"([^"]+)/;
push @{$result{$type}}, split ' ', $components;      # all in one arrayref
#push @{$result{$type}}, [ split ' ', $components ]; # or as separate ones
}

这需要多行带有COMPONENTS和/或PACKAGES(或任何其他前导关键字),并假设它们彼此无关,因此需要单独存储。

请澄清这些假设是否有误。

上面的代码创建哈希

( 组件 => [ 'A0000', 'B0000', 'G0000', ... ], 包 => [ ... ], )

其中[ ... ]是一个 arrayref,其中包含该关键字的所有行中的组件。

或者,如果使用代码中注释掉的行而不是上面的行,

( 组件 => [ ['A0000', 'B0000', 'G0000'], [ ... ], ... ], 包 => [ [ ... ], [ ... ], ... ], )

其中[ ... ]是带有一行组件的数组引用,这些组件都存储在一个数组引用中,数组引用是键的值。因此,这里每行的组件都是单独存储的,而不是像前面的情况那样全部存储在一个 arrayref 中。

如果=之前有任何其他单词,它们将存储为自己的键,并带有自己的 arrayref(s) 以及来自这些行的数据。


对澄清的更新

由于引号可能存在,也可能不存在,因此第一个引号是可选的,带有?

/(w+)s*=s*"?[^"]+)/;

而尾随的不需要处理,因为其余数据需要匹配

我将在这里提出一种不同的方法。您的正则表达式模式变得越来越复杂,这不是一个好主意。

问题的核心是,要进行重复匹配,您也需要匹配前缀文本,显然只能匹配一次。

但是,与其试图使您的正则表达式模式更加复杂,答案是以不同的方式解决问题。

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my %conf = do { local $/; <DATA> } =~ m/ (w+) =" ([^"]+) " /xg; 
print Dumper %conf; 
__DATA__
COMPONENTS="A0000 B0000 G0000"
PACKAGES="C0000 D0000 E0000"

这将创建一个数据结构。

$VAR1 = {
'COMPONENTS' => 'A0000 B0000 G0000',
'PACKAGES' => 'C0000 D0000 E0000'
};

如果需要单独使用值。

$_ = [split] for values %conf;
print Dumper %conf; 

这在功能上等同于此。

foreach my $key ( keys %conf ) {
#split the value on whitespace.
my @stuff = split ' ', $conf{$key};
#replace it with your array. 
$conf{$key} = @stuff;

}

它产生

$VAR1 = {
'PACKAGES' => [
'C0000',
'D0000',
'E0000'
],
'COMPONENTS' => [
'A0000',
'B0000',
'G0000'
]
};

所以现在你可以写这个了。

foreach my $value ( @{$conf{'COMPONENTS'}} ) { 
print $value,"n";
}

相关内容

  • 没有找到相关文章

最新更新