Regex 是否将触发器的结果保存在变量中?

Regex 是否将触发器的结果保存在变量中?,regex,perl,Regex,Perl,我有大约1kB的文本来自STDIN my $f = join("", <STDIN>); my$f=join(“,”); 我想得到open1和close1之间的内容,所以我想到了/open1/./close1/ 我只看到它在while循环和$\uu中的一行程序和脚本中使用过 问题 当所有内容都在$f中时,如何从脚本中的/open1/./close1/获得结果?您可以重写$f的生成方式,以便在循环时利用中的触发器: my ( $f, $matched ); while ( <

我有大约1kB的文本来自STDIN

my $f = join("", <STDIN>);
my$f=join(“,”);
我想得到
open1
close1
之间的内容,所以我想到了
/open1/./close1/

我只看到它在while循环和
$\uu
中的一行程序和脚本中使用过

问题


当所有内容都在
$f
中时,如何从脚本中的
/open1/./close1/
获得结果?

您可以重写
$f
的生成方式,以便在
循环时利用
中的触发器:

my ( $f, $matched );
while ( <> ) {
    $f .= $_;
    $matched .= $_ if /open1/ .. /close1/;
}
my($f$matched);
而(){
$f.=$\;
$matched.=$\uIf/open1//close1/;
}
使用单个正则表达式捕获所有匹配项 如果要捕获
open1
start1
标记(不包括标记)之间的所有行,可以使用单个正则表达式轻松完成:

my $f = join("", <STDIN>);

my @matches = ( $f =~ m/\bopen1\b(.*?)\bclose1\b/gs );

for my $m (@matches) {
  print "$m";
}
注意,可以使用任意Perl表达式作为range运算符的操作数。我不推荐这段代码,因为它效率不高,可读性也不强。同时,很容易将第一个示例改编为匹配集合中包含
open1
close1
标记的情况,例如:

my @matches = ( $f =~ m/\bopen1\b(.*?)\bclose1\b/gs );
for my $m (@matches) {
  print "open1${m}close1\n";
}
你也可以雇佣。获取第一对
open1
close1

my $open_to_close = (split /open1|close1/, $f)[1];
分隔符可以是
open1
close1
,因此返回的是三个元素的列表:在
open1
之前、它们之间和
close1
之后。我们考虑第二个因素


如果有更多的
open1
/
close1
对,则取所有奇数索引元素

或者也获取数组

my @parts = split /open1|close1/, $f;

my @all_open_to_close = @parts[ grep { $_ & 1 } 0..$#parts ];
或者直接从列表中获取

my @all_open_to_close = 
    grep { CORE::state $i; ++$i % 2 == 0 }  split /open1|close1/, $f;
这是一个
v5.10
。如果您已经使用了不需要的
核心::
前缀。

另一种方法是从
$f
的内容中创建新的输入流

open my $fh, '<', \$f;
while (<$fh>) {
    if (/open1/ .. /close1/) {
        ...
    }
}

打开我的$fh',因此您希望从
/open1/
/close1/
的行存储在
$f
中?理想情况下,结果应该放在另一个变量中,这样
$f
不会被覆盖。
$matched
在使用
$f=“xxx open1 ddd close1 mmm”进行测试时为空@JasmineLognnes在单独的行中是“open1”和“close1”@JasmineLognnes,如果您实际将
xxx open1 ddd close1 mmm
传递给STDIN,它会起作用。你一定改变了什么。你不知道开始标记和结束标记是否在不同的行上。如果你能解释一下为什么触发器不能工作,那就太好了。@simbabque,我已经添加了解释。我想你现在可以取消你的反对票了,那不是我的。你的答案已经很好了,但还可以改进。
open my $fh, '<', \$f;
while (<$fh>) {
    if (/open1/ .. /close1/) {
        ...
    }
}