$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: $'"
}
}
这印刷了整个字符串。我使用了$'函数,但它占用了太多数据。我如何限制它?
如果我只想“昨天和后一天”打印怎么办?我怎样才能在中间开始匹配脚本?
答案 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";
}