regex - 将触发器的结果保存在变量中?

标签 regex perl

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

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

我想获取open1close1之间的内容,所以想到了/open1/../close1/

我只看到它被用在一个线程和 while 循环和 $_ 的脚本中。

问题

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

最佳答案

用一个正则表达式捕获所有匹配项

如果你想捕获 open1start1 标记 (不包括标记) 之间的所有行,只需一个正则表达式:

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

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

for my $m (@matches) {
  print "$m";
}

在哪里

  • s 修饰符将字符串视为单行;
  • g修饰符捕获所有匹配;
  • (.*?) 使用 lazy quantifier 匹配一组任意字符

使用范围运算符

如果您想避免捕获标记,范围运算符(所谓的触发器)对于此任务不是很方便,因为像 /open1/../close1/ 这样的表达式会返回true 匹配模式的行。

表达式 /^open1$/../^close1$/ 返回 false 直到 /^open1$/真的。左边的正则表达式一旦与该行匹配就停止求值,并一直返回 true 直到 /^close1$/ 变为 true。当正确的表达式匹配时,循环重新开始。因此,open1close1 标记包含在 $matches 中。

如果输入保存在变量中就更不方便了,因为你需要逐行读取变量的内容,例如:

my $matches = "";
my @lines = split /\n/, $f;
foreach my $line (@lines) {
  if ($line =~ m/^open1$/ .. $line =~ m/^close1$/) {
    $matches .= "$line\n";
  }
}

请注意,可以使用任意 Perl 表达式作为范围运算符的操作数。我不推荐这段代码,因为它效率不高,而且可读性不强。同时,第一个示例很容易适应 open1close1 标记包含在匹配集中的情况,例如:

my @matches = ( $f =~ m/\bopen1\b(.*?)\bclose1\b/gs );
for my $m (@matches) {
  print "open1${m}close1\n";
}

关于regex - 将触发器的结果保存在变量中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41428316/

相关文章:

perl - 如何使用 perl 语言在 selenium 远程驱动程序中打开新选项卡并打开 url

java - 正则表达式查找特定字符在字符串中是否存在奇数次

SQL 查询进行反向 CONTAINS 搜索?

xml - 如何使用 perl 解析带有 nameapce 的 redhat 警报 xml 文件

regex - 有什么作用? : in a regular expression mean?

arrays - Perl 概念动态引用数组

perl - Bing Api如何制作过滤器

python - 正则表达式不能匹配多个相同类型的组

regex - 如何提取文件中的字符串并替换特定的模式文本

javascript - 使用 JavaScript 的正则表达式