-9

交叉张贴在 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

4 回答 4

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

于 2012-06-18T19:35:46.217 回答
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 does not eval '/(...)/' set $1? 对于最近的示例,Perl 不会更新到下一个匹配项,因为它在更复杂的程序中很容易出错。相反我教的是简单地使用匹配操作的返回值,它没有$1$`和朋友们的缺点。

于 2012-06-18T19:39:24.933 回答
0

这是一个开始。

if ($String =~ /hello (.*?) yesterday/i) {
    print $1;
}
于 2012-06-18T18:44:30.177 回答
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";
}
于 2012-06-18T18:47:22.147 回答