我无法提取出以下示例中需要删除的一系列行。 $ end_pattern的正则表达式似乎不匹配。
请让我知道我错过了什么。非常感谢
#!/usr/bin/perl
$begin_pattern = 'Fac.*Begin-to-search';
$end_pattern = 'Mix.*End-to-search';
open(IN, "Input.txt") || die "Can't open file!\n";
my @lines = <IN>;
foreach $line (@lines) {
$line =~ s/^\s+//; #remove leading spaces
$line =~ s/\s+$//; #remove trailing spaces
if ($line =~ /$begin_pattern ... $end_pattern/) {
print "$line\n";
}
# Next, delete this range of lines
}
"Input.txt" file listed below:
-----------
something for storing 0
No. of blocks : 0
Filt Nothing Nothing
Fac Y 0 Mix 0 Mix Mix 0 Begin-to-search
96 Fac Y 0 60 0 900 60 0 0 0
806 Fac Y 0 0 0 0 0 0 0 0
Fac A|B|C|D Y 11 0 0 0 0 0
340 Fac A|B|C|D Y 11 0 0 0 0 0 0 0
Mix M Y 11 Mix Mix 0 Mix 0 End-to-search
573 Wrn A|B|C|D Y 11 0 0 0 0 0 0 0
Mix M Y 11 60 Mix 0 60 0 ware
带警告的修改代码:(见下面的问题)
#!/usr/bin/perl
use warnings;
use strict;
my $begin_pattern = 'Fac.*Begin-to-search';
my $end_pattern = 'Mix.*End-to-search';
open(IN, "Input.txt") || die "Can't open file!\n";
my @lines = <IN>;
foreach my $line (@lines) {
$line =~ s/^\s+//;
$line =~ s/\s+$//;
if(defined $line) { print "\$line is initialized\n"; }
else { print "\$line is uninitialized\n"; }
if ($line =~ /$begin_pattern/ ... /$end_pattern/) {
print "$line";
}
if ($line =~ /$end_pattern/) {
last;
}
}
答案 0 :(得分:2)
if ($line =~ /$begin_pattern/ .. $line =~ /$end_pattern/)
所以你只是缺少$line =~
第二个条件。
将qr operator用于正则表达式更好,您可以在此处有效使用$_
variable
use warnings;
use strict;
my $begin_pattern = qr/Fac.*Begin-to-search/;
my $end_pattern = qr/Mix.*End-to-search/;
my $file = 'Input.txt';
open my $fh, '<', $file or die "Can't open $file: $!";
while (<$fh>)
{
s/^\s+//;
s/\s+$//;
if (/$begin_pattern/ .. /$end_pattern/) {
print;
}
}
close $fh;
这仅打印由正则表达式匹配的标记之间的行
Fac Y 0 Mix 0 Mix Mix 0 Begin-to-search 96 Fac Y 0 60 0 900 60 0 0 0 806 Fac Y 0 0 0 0 0 0 0 0 Fac A|B|C|D Y 11 0 0 0 0 0 340 Fac A|B|C|D Y 11 0 0 0 0 0 0 0 Mix M Y 11 Mix Mix 0 Mix 0 End-to-search
其他几点说明
请始终以use warnings;
和use strict;
建议使用三个参数open
,以及更好的
当您打印错误消息时,请使用$! variable查看实际消息
逐行处理文件,除非有特定原因要先读取所有行
本说明主要汇总了评论,解释了问题中代码的行为。
该行(在原始版本中,在问题编辑中更正)
if ($line =~ /$begin_pattern/ ... /$end_pattern/)
真的是
if ($line =~ /$begin_pattern/ ... $_ =~ /$end_pattern/)
由于/.../
始终与$_
匹配,因此默认为foreach my $line (@lines)
。
然而,在循环$line
中,我们引入了一个词法变量来迭代($_
别名元素)然后我们没有得到$_
;它没有为循环定义。所以第二种模式永远不会匹配,正如观察到的那样。
请注意,来自更高范围的$_
- 例如,某些外部循环 - 可能仍会在循环中看到。
解决方案是通过foreach (@lines)
启用while (<$fh>)
作为主题化工具(或在答案if (/$begin_pattern/ .. /$end_pattern/)
中逐行阅读),然后使用
$_
匹配foreach my $line (@lines) {
# ...
if ($line =~ /$begin_pattern/ ... $line =~ /$end_pattern/)
,或设置变量并在两个条件中使用
..
请注意,...
和$_
实际上有所不同。请参阅链接文档。
实际上,在循环开始时也可以设置$line
(到class ViewController: UIViewController {
var observer: CFRunLoopObserver!
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.global().async {
self.observer = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, CFRunLoopActivity.beforeWaiting.rawValue, false, 0) { (observer, activity) in
self.doSomething()
}
CFRunLoopAddObserver(CFRunLoopGetCurrent(), self.observer, .commonModes)
}
}
func doSomething() {
// this is intentionally blank
}
deinit {
print("deinit")
}
}
),然后发布的代码将按原样运行。至少可以说,这显然很尴尬。
答案 1 :(得分:1)
您尝试匹配$begin_pattern
和$end_pattern
之间的所有内容,但是您逐行读取文件,因此它永远不会匹配,因为这些模式不会出现在同一行上。
分别检查每个图案,记住您是否在所需的线条块中,然后打印。
#!/usr/bin/perl
use strict;
use warnings;
my $begin_pattern = 'Fac.*Begin-to-search';
my $end_pattern = 'Mix.*End-to-search';
my $in_block = 0;
foreach my $line (<DATA>) {
$line =~ s/^\s+//; #remove leading spaces
$line =~ s/\s+$//; #remove trailing spaces
$in_block = 1 if ($line =~ m/$begin_pattern/);
$in_block = 0 if ($line =~ m/$end_pattern/);
print "$line\n" if ($in_block);
}
__DATA__
something for storing 0
No. of blocks : 0
Filt Nothing Nothing
Fac Y 0 Mix 0 Mix Mix 0 Begin-to-search
96 Fac Y 0 60 0 900 60 0 0 0
806 Fac Y 0 0 0 0 0 0 0 0
Fac A|B|C|D Y 11 0 0 0 0 0
340 Fac A|B|C|D Y 11 0 0 0 0 0 0 0
Mix M Y 11 Mix Mix 0 Mix 0 End-to-search
573 Wrn A|B|C|D Y 11 0 0 0 0 0 0 0
Mix M Y 11 60 Mix 0 60 0 ware