perl - perl 在两个关键字之间抓取文本
问题描述
我正在尝试阅读两个关键字之间的文本。虽然不是真的工作。我想要的只是阅读问题和答案,然后打印出来。它不起作用,只是继续打印出一个非常大的循环。
#!/usr/bin/perl
use strict ;
use warnings;
my $question ;
my $answer ;
while(my $line = <>){
chomp $line ;
if ($line =~ /questionstart(.*)questionend/) {
$question = $1 ; }
elsif ($line =~ /answerstart(.*)answerend/) {
$answer = $1 ; }
my $flashblock = <<"FLASH" ;
<!-- BEGIN -->
<p class="question">
$question
</p>
<p class="answer">
$answer
</p>
<!-- END -->
FLASH
print $flashblock ;
}
这是文件的示例
questionstart
hellphellohellohello
questionend
answerstart
hellohellohello
answerend
解决方案
由于文件是逐行读取的,因此跨越多行的搜索短语永远无法匹配。
解决此问题的一种基本方法是为问答区域设置标志。由于您有进入和离开这些区域的非常清晰的标记,因此代码非常简单
use warnings;
use strict;
use feature 'say';
my ($question, $answer);
my ($in_Q, $in_A);
while (my $line = <>) {
next if $line =~ /^\s*$/;
if ($line =~ /^\s*questionstart/) { $in_Q = 1; next }
elsif ($line =~ /^\s*questionend/) { $in_Q = 0; next }
elsif ($line =~ /^\s*answerstart/) { $in_A = 1; next }
elsif ($line =~ /^\s*answerend/) { $in_A = 0; next }
if ($in_Q) { $question .= $line }
elsif ($in_A) { $answer .= $line }
}
say "Question: $question";
say "Answer: $answer";
if-elsif
(为了简洁和强调,我在这里精简了陈述)
这段代码对输入文件做了一些合理的假设。我需要标记开始行(可能有空格),但允许在它们后面添加更多文本。如果您想确保它们是该行中唯一的东西,请在$
正则表达式的末尾添加锚点(再次使用\s*
)。
据说输入有一个Q/A。如果它曾经更改为多个,则在循环内移动打印,一旦答案结束就这样elsif (/^\s*answerend/) { .. }
问题中的印刷很好,所以我在这里不再重复。如果有机会打印 HTML 以外的格式,则从前导和尾随空格、多个空格和换行符中清除生成的字符串。
对同一个变量的重复测试可能会导致人们寻找一个案例类型的构造,在 Perl 中就是switch。但是,这仍然是一个实验性功能,其运作方式
很难准确描述
(文档!)。此外,它还可能涉及智能匹配,这很难描述,被广泛理解为以当前形式被破坏,并且肯定会改变。所以我建议坚持使用级联 if-elsif 语句(在这种方法中)。
推荐阅读
- react-native - React Native:将文本完美对齐
- javascript - Discord 错误无法读取属性“isFocused”
- javascript - moment().startOf('month').day() // => 0?
- prolog - Prolog 中的产品
- php - 做while循环不输出数据
- arrays - IndexError:使用偏相关函数的元组索引超出范围
- java - 一段时间后运行和中断线程
- algorithm - 为函数找到正确的复杂度类
- javascript - 如果我从外部数据加载,如何更新 d3 图形?
- sql-server - 考勤SQL语句from to