如何提取某个单词后面的数据?

时间:2012-06-18 18:40:36

标签: regex perl regex-greedy

Cross-posted at Perlmonks

$String = "hello I went to the store yesterday and the day after and the day after";

我只想打印i went to the store字样。我尝试了两种方法,但都没有用:

if ($String =~ /hello/i) {
    until ($String =~ /yesterday/i) {
        print "Summary: $'"
    }
}

这印刷了整个字符串。我使用了$'函数,但它占用了太多数据。我如何限制它?

如果我只想“昨天和后一天”打印怎么办?我怎样才能在中间开始匹配脚本?

4 个答案:

答案 0 :(得分:1)

首先,之前的答案使用$1,但我讨厌在没有必要时使用全局变量。这里没有必要。

其次,之前的答案假设您不想捕捉换行符,但您没有说出任何类似的内容。

修正:

if (my ($match) = $s =~ /hello (.*?) yesterday/s) {
   say $match;
}

最后,使用?贪婪修饰符会导致意外(特别是如果您在单个模式中使用多个)。如果给出

hello foo hello bar yesterday

以上正则表达式将捕获

foo hello bar

如果你想要

bar

请改用以下内容:

if (my ($match) = $s =~ /hello ((?:(?!yesterday).)*) yesterday/s) {
   say $match;
}

(?:(?!STRING).)STRING[^CHAR]CHAR

答案 1 :(得分:1)

这回答了原始问题和后续行动。

use strict;
use warnings FATAL => 'all';
my $String = 'hello I went to the store yesterday and the day after and the day after';
my ($who_what_where) = $String =~ /hello (.*) yesterday/;
# 'I went to the store'

匹配字符串的中间是默认行为,它与第一个示例没有区别。

my ($when) = $String =~ /store (.*) and/;
# 'yesterday and the day after'

我不建议初学者使用$1$`,这通常会有问题,请参阅Perl: Why doesn't eval '/(...)/' set $1?Perl doesn't update to next match了解最近的例子如何容易出错在更复杂的计划中。相反,我教的只是使用匹配操作的返回值,它没有$1$`和朋友的缺点。

答案 2 :(得分:0)

这是一个开始。

if ($String =~ /hello (.*?) yesterday/i) {
    print $1;
}

答案 3 :(得分:0)

您可以使用括号()$1$2作为第二个括号组等)来捕获文本。

use strict;
use warnings;  # always use these 

my $string= "hello I went to the store yesterday and the day after " ;

if (/hello (.*?) yesterday/i) {
    print "Summary: $1\n";
}