我想遍歷 Perl 中的多行模式,但我在語法上苦苦掙扎。
我的輸入字串是:
STAR-WARS 2020-01-01 00:00:00 00:00
S&W #00000000
%%SHOW NAME: Q=Kenobi;%%
RETCODE = 0 Operation success
In-universe information
-----------------------
Species = Human
Gender = Male
television series of num = whatever
(Number of results = 1)
Personal Details
----------------
First Name = Obi-Wan
Last Name = Kenobi
Alias = Padawan
= Jedi Knight
= Jedi General
= Jedi Master
Points to other set of information = whatever
(Number of results = 1)
Other attribute
---------------
Significant other = Satine Kryze
Affiliation = Jedi Order
= Galactic Republic
= Rebel Alliance
Occupation = Jedi
(Number of results = 1)
--- END
我想要的結果哈希是:
$VAR1 = {
'In-universe information' => {
'Gender' => 'Male',
'Species' => 'Human',
'results' => '1',
'television series of num' => 'whatever'
},
'Other attribute' => {
'Affiliation' => [
'Jedi Order',
'Galactic Republic',
'Rebel Alliance'
],
'Occupation' => 'Jedi',
'Significant other' => 'Satine Kryze',
'results' => '1'
},
'Personal Details' => {
'Alias' => [
'Padawan',
'Jedi Knight',
'Jedi General',
'Jedi Master'
],
'First Name' => 'Obi-Wan',
'Last Name' => 'Kenobi',
'Points to other set of information' => 'whatever',
'results' => '1'
},
'code' => '0',
'description' => 'Operation success'
};
我想出的東西適用于“單塊”(例如Personal Details上面)。但是,如果資料包含多個塊,我無法弄清楚如何遍歷每個匹配的塊。(例如while與 一起使用/g)
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
local $/;
my $output = <DATA>;
my %hash;
($hash{'code'}, $hash{'description'}) = $output =~ /^RETCODE = (\d )\s (.*)\n/m;
if ($hash{'code'} eq "0") {
my ($type,$data, $results) = $output =~ /([^\n] )\n- \n(.*)\n\n\(Number of results = (\d )\)\n\n/sm;
my $previousKey = "";
while ($data =~ /(. )$/mg) {
my $line = $1;
$line =~ s/(?:^ )//g;
my ($key, $value);
if ($line =~ /^\s*= /) {
($value) = $line =~ /^\s*= (.*)$/;
$hash{$type}{$previousKey} = [ $hash{$type}{$previousKey} ] unless ref($hash{$type}{$previousKey});
push (@{$hash{$type}{$previousKey}}, $value);
} else {
($key, $value) = split(/ = /, $line);
$hash{$type}{$key} = $value;
$previousKey = $key;
}
}
say STDERR Dumper(\%hash);
}
__DATA__
STAR-WARS 2020-01-01 00:00:00 00:00
S&W #00000000
%%SHOW NAME: Q=Kenobi;%%
RETCODE = 0 Operation success
In-universe information
-----------------------
Species = Human
Gender = Male
television series of num = whatever
(Number of results = 1)
Personal Details
----------------
First Name = Obi-Wan
Last Name = Kenobi
Alias = Padawan
= Jedi Knight
= Jedi General
= Jedi Master
Points to other set of information = whatever
(Number of results = 1)
Other attribute
---------------
Significant other = Satine Kryze
Affiliation = Jedi Order
= Galactic Republic
= Rebel Alliance
Occupation = Jedi
(Number of results = 1)
--- END
幾個事實:
- 每個“塊”總是包含一個標題,后跟換行符和等于標題長度的破折號。
- 每個“塊”總是以 結尾
\n,然后是(Number of results = \d ),然后是\n。 - 每個鍵/值對總是在等號前后有兩個空格。IE
/ = / - 當不存在鍵時,假設它是一個 [array],并將值附加到前一個鍵。例如
Alias在我上面的例子中。 - 該字串將始終以后
--- END跟\n
uj5u.com熱心網友回復:
根據您的描述,該部分以 . 開頭 ...和結尾--- END。
基于此資訊,可以使用正則運算式將輸入劃分為感興趣的塊,然后使用決議器在回圈中單獨處理這些塊以構建散列。
注意:決議器稍作修改并放入子程式
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my @shows;
my $data = do { local $/; <DATA> };
my @blocks = $data =~ /^(\ \ \ .*?^--- END)/msg;
push @shows, parse($_) for @blocks;
say Dumper(\@shows);
exit 0;
sub parse {
my $data = shift;
my(@sections,$re,$r);
# Alternative block to extract show info section
# $re = qr/^\ \ \ \s (\S )\s (\S )\s (\S )\s \S \s (\S )\s %%[^:] ?:\s ([^;] ?);%%\s RETCODE = (\d )\s ([^\n] )/;
# $r->{info}->@{qw/show day time sw show_name code description/} = $data =~ /$re/;
$re = qr/RETCODE = (\d )\s ([^\n] )/;
$r->@{qw/code description/} = $data =~ /$re/;
@sections = $data =~ /\n\n(. ?\n- .*?\(Number of results = \d \))/gs;
for my $block ( @sections ) {
my($section,@lines,$key,$value);
@lines = split("\n",$block);
$section = $lines[0];
for my $line (@lines[2..$#lines-2] ) {
$line =~ s/^\s //;
if( $line =~ /^=\s (. )/ ) {
$r->{$section}{$key} = [ $r->{$section}{$key} ] unless ref $r->{$section}{$key} eq 'ARRAY';
push @{$r->{$section}{$key}}, $1;
} else {
($key,$value) = split(/ = /,$line);
$r->{$section}{$key} = $value;
}
}
$r->{$section}{results} = $block =~ /\(Number of results = (\d )\)/gs;
}
return $r;
}
__DATA__
STAR-WARS 2020-01-01 00:00:00 00:00
S&W #00000000
%%SHOW NAME: Q=Kenobi;%%
RETCODE = 0 Operation success
In-universe information
-----------------------
Species = Human
Gender = Male
television series of num = whatever
(Number of results = 1)
Personal Details
----------------
First Name = Obi-Wan
Last Name = Kenobi
Alias = Padawan
= Jedi Knight
= Jedi General
= Jedi Master
Points to other set of information = whatever
(Number of results = 1)
Other attribute
---------------
Significant other = Satine Kryze
Affiliation = Jedi Order
= Galactic Republic
= Rebel Alliance
Occupation = Jedi
(Number of results = 1)
--- END
STAR-WARS 2020-01-01 00:00:00 00:00
S&W #00000000
%%SHOW NAME: Q=Kenobi;%%
RETCODE = 0 Operation success
In-universe information
-----------------------
Species = Human
Gender = Male
television series of num = whatever
(Number of results = 1)
Personal Details
----------------
First Name = Obi-Wan
Last Name = Kenobi
Alias = Padawan
= Jedi Knight
= Jedi General
= Jedi Master
Points to other set of information = whatever
(Number of results = 1)
Other attribute
---------------
Significant other = Satine Kryze
Affiliation = Jedi Order
= Galactic Republic
= Rebel Alliance
Occupation = Jedi
(Number of results = 1)
--- END
輸出
$VAR1 = [
{
'Other attribute' => {
'Significant other' => 'Satine Kryze',
'Occupation' => 'Jedi',
'results' => 1,
'Affiliation' => [
'Jedi Order',
'Galactic Republic',
'Rebel Alliance'
]
},
'Personal Details' => {
'results' => 1,
'First Name' => 'Obi-Wan',
'Alias' => [
'Padawan',
'Jedi Knight',
'Jedi General',
'Jedi Master'
],
'Points to other set of information' => 'whatever',
'Last Name' => 'Kenobi'
},
'code' => '0',
'description' => 'Operation success',
'In-universe information' => {
'television series of num' => 'whatever',
'Gender' => 'Male',
'results' => 1,
'Species' => 'Human'
}
},
{
'Other attribute' => {
'Affiliation' => [
'Jedi Order',
'Galactic Republic',
'Rebel Alliance'
],
'results' => 1,
'Significant other' => 'Satine Kryze',
'Occupation' => 'Jedi'
},
'Personal Details' => {
'First Name' => 'Obi-Wan',
'results' => 1,
'Last Name' => 'Kenobi',
'Alias' => [
'Padawan',
'Jedi Knight',
'Jedi General',
'Jedi Master'
],
'Points to other set of information' => 'whatever'
},
'code' => '0',
'description' => 'Operation success',
'In-universe information' => {
'television series of num' => 'whatever',
'results' => 1,
'Gender' => 'Male',
'Species' => 'Human'
}
}
];
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/493829.html
下一篇:評估分配給變數的條件
