我是perl的绝对初学者,我试图在不同行上的2个字符串之间提取文本行,但没有成功。看起来我在代码中遗漏了一些东西。代码应该打印出文件名和找到的字符串。你知道问题出在哪里吗?非常感谢您的帮助或建议。这是一个例子:
*****************
example:
START
new line 1
new line 2
new line 3
END
*****************
和我的剧本:
use strict;
use warnings;
my $command0 = "";
opendir (DIR, "C:/Users/input/") or die "$!";
my @files = readdir DIR;
close DIR;
splice (@files,0,2);
open(MYOUTFILE, ">>output/output.txt");
foreach my $file (@files) {
open (CHECKBOOK, "input/$file")|| die "$!";
while ($record = <CHECKBOOK>) {
if (/\bstart\..\/bend\b/) {
print MYOUTFILE "$file;$_\n";
}
}
close(CHECKBOOK);
$command0 = "";
}
close(MYOUTFILE);
答案 0 :(得分:4)
我想你在这里试图使用一个触发器,这可能适合你的输入,但是你写错了:
if (/\bstart\..\/bend\b/) {
触发器(范围运算符)使用两个语句,由..
或...
分隔。你想要的是与..
加入的两个正则表达式:
if (/\bSTART\b/ .. /\bEND\b/)
当然,您还希望匹配大小写(上部),或使用/i
修饰符忽略大小写。您甚至可能希望使用行锚^
的开头仅匹配行的开头,例如:
if (/^START\b/ .. /^END\b/)
您还应该知道您的整个程序可以替换为单行程序,例如
perl -ne 'print if /^START\b/ .. /^END\b/' input/*
唉,这只适用于linux。 Windows中的cmd shell不会为glob,因此您必须手动执行此操作:
perl -ne "BEGIN { @ARGV = map glob, @ARGV }; print if /^START\b/ .. /^END\b/" input/*
如果您在整个文件打印时遇到麻烦,无论您做什么,我认为问题在于您的输入文件。所以花点时间研究它并确保它是你认为的那样,例如:
perl -MData::Dumper -e"$Data::Dumper::Useqq = 1; print Dumper $_;" file.txt
答案 1 :(得分:0)
如果你匹配多行字符串,你可能需要告诉正则表达式:
if (/\bstart\..\/bend\b/s) {
请注意正则表达式后的s
。
Perldoc说:
- s
将字符串视为单行。也就是说,改变“。”匹配任何 任何角色,甚至是换行符,通常不会 匹配。