我的输入文件格式为
hidestart
machine learning
hideend
rule abc {
hidestart
Keep Learning
hideend
-abc [ time=good]
}
rule abc1 {
Keep Learning
-abc1 [ time1=fail]
}
Rule “abc” {
hidestart
dp a.E_t_C1 temp –be_good NL LP -expr " (cnt(a.E_t_C1) > 0) ? expr(- (minus (pt(a.E_t_C1,ab)) / at(temp)*fr/pr_1)) : 1 " < 0 > 1
hideend
…..
-CDE [ ABC_TYPE = “temp_EOL”]
-CDE [ TMP_RUL = “a.E” ]
.. .. ..
-comment "keepTrying"
}
我希望将位于规则块内的hideend移动到最后并且在花括号之前。仅当规则块具有hidestart命令时,才应插入/移动此hideend。此外,位于此规则块之外的hidestart / hidened应保持不变。
预期产出:
hidestart
machine learning
hideend
rule abc {
hidestart
Keep Learning
-abc [ time=good]
hideend
}
rule abc1 {
Keep Learning
-abc1 [ time1=fail]
}
Rule “abc” {
hidestart
dp a.E_t_C1 temp –be_good NL LP -expr " (cnt(a.E_t_C1) > 0) ? expr(- (minus (pt(a.E_t_C1,ab)) / at(temp)*fr/pr_1)) : 1 " < 0 > 1
…..
-CDE [ ABC_TYPE = “temp_EOL”]
-CDE [ TMP_RUL = “a.E” ]
.. .. ..
-comment "keepTrying"
hideend
}
我当前的代码,实际上是删除了位于块之外的hideend,并且还将hideend添加到我没有hidestart的规则块中。请帮我修复下面的代码
!/usr/bin/env perl
use strict();
use warnings();
use Data::Dumper;
my $ruleData=0;
my $goldenData = $ARGV[0];
open( $fopen, "< $goldenData") or die "cannot open $!";
while(<$fopen>) {
if ( $_ =~ /^\s*rule(.+)/gi ) {
print "rule$1\n";
while($tmp=<$fopen> ) {
if ( $tmp =~ /^\s*hideend/gi ) { next; }
if ( $tmp =~ /^\s*\}/gi ) {
print "hideend\n$1\}\n";
} else {
print "$tmp";
}
}
close($tmp);
} else {
print "$_";
}
}
close($fopen);
如果有任何问题,请告诉我。
提前致谢。
此致 Divesh
答案 0 :(得分:0)
请试试这个:
#!/usr/bin/env perl
use strict();
use warnings();
use Data::Dumper;
my $ruleData=0;
my $goldenData = $ARGV[0];
open(IN, "<$goldenData") or die "cannot open $!";
local $/; $_=<IN>; my $tmp=$_;
close(IN);
my $CurBrLoopMany = qw/((?:[^{}]*(?:{(?:[^{}]*(?:{(?:[^{}]*(?:{[^{}]*})*[^{}]*)*})*[^{}]*)*})*[^{}]*)*)/;
my ($_pre,$_match,$_post) = "";
while($tmp=~m/rule([\"A-z\s]*)\{$CurBrLoopMany\}/gis)
{
$_pre = $_pre.$`; $_match = $&; $_post = $';
$_match=~s/\s*hideend//g;
$_match=~s/\}/ hideend \n}/i;
$_pre = $_pre.$_match; $tmp = $_post;
}
if(length $_pre) { $tmp = $_pre.$_post; }
print $tmp;
感谢。
答案 1 :(得分:0)
这适用于您的示例文件。并且,希望这些评论能够清楚说明发生了什么,以便您可以解决任何问题。
#!/usr/bin/perl
use strict;
use warnings;
my ($found_hidestart, $found_hideend);
while (<>) {
# Only process within a rule block
if (/^rule\s+\S+\s+{/i .. /^}/) {
# If we find 'hidestart' remember that
if (/\bhidestart\b/) {
$found_hidestart = 1;
}
# If we find 'hideend' (and have already found 'hidestart')
# remember that and don't print this line.
if (/\bhideend\b/ && $found_hidestart) {
$found_hideend = 1;
next; # skip printing
}
# If we're at the end of a block and we've previously found
# both 'hidestart' and 'hideend', then print 'hideend'.
if (/^}/) {
print " hideend\n" if $found_hidestart and $found_hideend;
# Forget what we've previously found
$found_hidestart = $found_hideend = 0;
}
}
print;
}
它被编写为Unix过滤器 - 因此它从STDIN读取并写入STDOUT。这比打开显式文件名更灵活。假设这是在一个名为reformat
的文件中,你可以这样称呼它:
$ ./reformat < your_existing_file > your_new_file
更新:我已稍微更新了正则表达式,因此它会处理您展开的示例。