我正在通过阅读Jeffrey Friedl的优秀Mastering Regular Expressions来教自己Perl和Regex。
在尝试解决从第53页开始的“小邮件实用程序”练习时,我偶然发现了一个问题,即不知道如何将文件内容保存到从偏移开始的变量中。< / p>
所以这是我的(缩短的)剧本。 我做了一些在线研究,但无法弄清楚如何将文件的其余部分(即电子邮件正文)放入变量$ body中。 我发现我可以使用 最终,我最终将文件的行首先放入数组中,但不满意solution。 如何将文件内容从偏移量(作为行号或字节)保存到$ body中? 修改
我的解决方案 - 由vstm提供 - 是在遇到标记正文开头的空行时使用 虽然这对我来说很有用,但我仍然想知道如何在Perl中说(优雅地)“给我这个文件的x到z行。” 感谢大家的建议。my ($body, $line, $subject);
$body = $line = $subject = "";
open(MYFILE, "king.in") || die("Could not open file!");
# Read the file's content line by line
while ($line = <MYFILE>)
{
# An empty line marks the beginning of the body
if ($line =~ m/^\s+$/ ) {
# HERE IS THE ISSUE
# Save the file content starting from the current line
# to the end of the file into $body
last;
}
if ($line =~ m/^subject: (.*)/i) {
$subject = $1;
}
# Parse additional data from the mail header
}
close(MYFILE);
print "Subject: Re: $subject\n";
print "\n" ;
print $body;
$pos = tell(MYFILE);
$body = join("", <MYFILE>)
读取文件的其余部分。
我写的整个脚本可以找到here。
答案 0 :(得分:2)
变量$.
将为您提供当前文件句柄的行号。文档here.
如果要在文件中获取字节偏移量,可以使用seek
设置文件句柄位置。但通常情况下,你真的不想这样做,除非字节实际上是你想要的偏移量。
最简单的解决方案可能是使用输入记录分隔符。将其设置为undef
将会污染文件,而不是逐行读取:
my $text;
my $subject;
while (<MYFILE>) {
if (/^subject: /i) { # /i flag to ignore case
$subject = $_;
} elsif (/^\s*$/) {
local $/;
$text = <MYFILE>;
}
}
这也将结束循环,因为它已达到eof。
答案 1 :(得分:1)
不要立即停止,你可以设置一个标志,上面写着“现在我正在读取身体”。像那样:
my $inbody = 0;
while ($line = <MYFILE>)
{
if($inbody) {
$body .= $line;
next;
}
# An empty line marks the beginning of the body
if ($line =~ m/^\s+$/ ) {
# HERE IS THE ISSUE
# Save the file content starting from the current line
# to the end of the file into $body
$inbody = 1;
next;
}
if ($line =~ m/^subject: (.*)/i) {
$subject = $1;
}
# Parse additional data from the mail header
}
这就像一台迷你状态机。首先它在“标题” - 状态中,如果读取第一个空换行符,它将切换到“body”状态,并将正文附加到变量。
或者,您可以将MYFILE
- 句柄的其余部分放入原始while
循环末尾和close
之前的正文:
# This would be your original while loop, (I've just shortened it)
while ($line = <MYFILE>)
{
if ($line =~ m/^\s+$/ ) {
last;
}
# Parse additional data from the mail header
}
# The MYFILE-handle is now still valid and at the beginning of the body
$body = join("", <MYFILE>);
# now you can close the handle
close(MYFILE);
答案 2 :(得分:0)
您可以更改输入记录分隔符:
local $/;
$body = <MYFILE>;