我一直在构建一个脚本来从IBM的SPSS Statistics包中获取一些输出并将其转换为SPSS输入语法。我目前遇到的问题似乎无法解决。我有一些看起来如下的文字:
VALUE LABELS V10
-1
1 "Yes".
VALUE LABELS V11
-50.00
-33.33
-10 "Don't Know".
我想替换引号中没有后跟标签的负值,并且没有带有标记为“-9”缺少“'的空格缩进,然后我想要捕获其中的每一个散列中的负值以及变量名称(即V10,V11),以便稍后我可以在重新编码语句中打印它们。我正在通过perl读取此文件,将“行”除以文字句点后跟一个新行(表示SPSS中命令的结束)。但是,到目前为止我提出的代码只是替换并捕获每个“行”的一个负值匹配,我不确定我做错了什么。我目前的代码如下:
my %negmiss;
my @lines = split(/(\.\n)/,$_);
foreach my $line (@lines) {
my $modline = $line;
if ($line =~ /VALUE LABELS\s(\S+)/g) {
my $label_name = $1;
if ($line =~ /\n(-\d+(\.\d+)?)\n/g) {
$modline =~ /\n(-\d+(\.\d+)?)\n/\n -9 \"Missing\"\n/g;
push my @negname, $label_name;
push @{$negmiss{$label_name}}, $1;
}
}
print $modline;
}
foreach (@negname) {
print "RECODE $_ (@{ $negmiss{$_} } = -9\.\n";
}
它部分有效,但同样,它只替换并捕获每个“行”的一个负值,所以我的输出看起来像这样:
VALUE LABELS V10
-9 "Missing"
1 "Yes".
VALUE LABELS V11
-9 "Missing"
-33.33
-10 "Don't Know".
RECODE V10 (-1 = -9).
RECODE V11 (-50.00 = -9).
如何捕获并替换V11“线”的-50.00和-33.33?
编辑:我希望我的输出看起来像这样:
VALUE LABELS V10
-9 "Missing"
1 "Yes".
VALUE LABELS V11
-9 "Missing"
-9 "Missing"
-10 "Don't Know".
RECODE V10 (-1 = -9).
RECODE V11 (-50.00 = -9).
RECODE V11 (-33.33 = -9).
答案 0 :(得分:0)
问题的根源在于:
Serializable
因为你的模式前缀为和后缀为/\n(-\d+(\.\d+)?)\n/\n -9 \"Missing\"\n/g;
,这意味着你的第二个“\ n”被前一个匹配所消耗 - 所以它不会匹配两次。
将其更改为
\n
(或者可能更好/\n(-\d+(\.\d+)?)(?=\n)/\n -9 \"Missing\"\n/g;
),它应该没问题。
E.g:
$
你的'推'线:
#!/usr/bin/env perl
use strict;
use warnings;
local $/ = '';
while ( <DATA> ) {
s/\n(-\d+(\.\d+)?)(?=\n)/\n -9 \"Missing\"/g;
print;
}
__DATA__
VALUE LABELS V10
-1
1 "Yes".
VALUE LABELS V11
-50.00
-33.33
-10 "Don't Know".
虽然不会做太多 - 最好不要这样做。我还建议你设置记录分隔符,因为这意味着你可以按记录工作。
设置为 push my @negname, $label_name;
的 $/
将在“段落模式”下工作 - 空白行分隔。
也许是这样的?:
''
这给出了输出:
#!/usr/bin/env perl
use strict;
use warnings;
my %recode;
local $/ = '';
while ( <DATA> ) {
my ( $label_name ) = m/VALUE LABELS (\S+)/;
my @recode = m/^\s*(\-[\d\.]+)$/gm;
$recode{$label_name} = \@recode;
s/\n(-\d+(\.\d+)?)(?=\n)/\n -9 \"Missing\"/g;
print;
}
print "\n\n";
foreach my $key ( sort keys %recode ) {
foreach my $value ( @{$recode{$key}} ) {
print "RECODE $key ( $value = -9 )\n";
}
}
__DATA__
VALUE LABELS V10
-1
1 "Yes".
VALUE LABELS V11
-50.00
-33.33
-10 "Don't Know".