a,1
b,2
c,3
d,4
({a
,b
,c
,d
是$var
和1
,2
... {{ 1}}(在我的代码中)
我要在$num
中搜索$var
,并用cell.txt
(如area
)替换$num
(对应的下一行)< / p>
area : 1
cell (a) {
area : 2
}
cell (b) {
area : 2.3
}
cell (c) {
area : 2.5
}
cell (d) {
area : 2.7
}
答案 0 :(得分:0)
我依靠一些更高级的正则表达式来尝试防御可能的输入并结合一些步骤。 docs on goto
建议last
(在您的情况下为last LABEL
)作为替代方案,但我希望OP不会因我回应某些人的教条而受到伤害。我的版本打印到标准输出,而不是更改原始文件,但应足够接近。打印一些预期的输出会有所帮助,但希望我猜对了。
Borodin在我之前几分钟结束,我看不到他的帖子,从某种程度上来说,这是一种更高级的方法。根据同一人的建议,我删除了对Regexp::Common
模块的引用,尽管相关,但我同意这个模块超出了需要。
#!/usr/bin/env perl
use Modern::Perl;
open(my $fh, '<', 'rerun.txt') or die "Could not open rerun.txt: $!";
my %new_area;
foreach (<$fh>) {
chomp;
my ($k, $v) = split ',';
die "invalid rerun format" unless ($k =~ /^\w+$/ and $v =~ /^[\d.]+$/);
$new_area{ $k } = $v;
}
open($fh, '<', 'cell.txt') or die "Could not open cell.txt: $!";
my $area_key;
while (<$fh>) {
if ( /^\s* cell \s*\(\s*(\w+)\s*\)\s* { \s*$/x ) {
$area_key = $1;
}
elsif (/^\s* } \s*$/x) {
undef $area_key
}
elsif ( defined($area_key) and /\barea\b/ and
exists $new_area{ $area_key }
) {
s/(area\s*:\s*)[\d.]+/$1$new_area{$area_key}/
}
print;
}
输出:
cell (a) {
area : 1
}
cell (b) {
area : 2
}
cell (c) {
area : 3
}
... etc ...
答案 1 :(得分:-1)
此解决方案使用第一列作为键,第二列作为值,将 rerun 数据读取到哈希%rerun
中。根据可能的键集构建正则表达式模式$re
并进行编译
cell.txt
的全部内容都被读入$cell
,以使其更容易处理多行字符串。找到每次出现cell (x) {
及其后继area : 99.99
且x
是%rerun
的键之一的情况,随后的99.99
被替换为哈希元素的值
找到并替换所有内容后,新的$cell
将打印到STDOUT
use strict;
use warnings 'all';
use autodie;
my %rerun = do {
open my $fh, '<', 'rerun.txt';
map { /[^,\s]/g } <$fh>;
};
my $cell = do {
open my $fh, '<', 'cell.txt';
local $/;
<$fh>;
};
my $re = join '|', sort { length $b <=> length $a } keys %rerun;
$re = qr/$re/;
$cell =~ s/ \b cell \s* \( \s* ( $re ) \s* \) \s* \{ \s* area \s* : \s* \K [\d.]+ /$rerun{$1}/gx;
print $cell;
cell (a) {
area : 1
}
cell (b) {
area : 2
}
cell (c) {
area : 3
}
cell (d) {
area : 4
}