-9

Perlmonks で相互投稿

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

私は単語を印刷したいだけですi went to the store。私は2つの方法を試しましたが、どちらもうまくいきませんでした:

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

これにより、文字列全体が出力されました。$' 関数を使用しましたが、データが多すぎました。どうすれば制限できますか?

「昨日と明後日」だけを印刷したい場合は?途中でスクリプトのマッチングを開始するにはどうすればよいですか?

4

4 に答える 4

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'

初心者には、問題が発生することが多いので、の使用はお勧めしません。Perlを参照$1してください。'/(...)/'が$ 1を設定しないのはなぜですか?また、 Perlは、最近の例では、より複雑なプログラムで簡単に失敗する可能性がある次の一致に更新されません。代わりに、一致操作の戻り値を使用することを教えています。これには、、および友人の欠点はありません。$`$1$`

于 2012-06-18T19:39:24.933 に答える
1

まず、以前の回答では を使用$1していますが、必要のない場合にグローバル変数を使用するのは嫌いです。ここでは必要ありません。

第二に、以前の回答では、改行をキャプチャしたくないと想定していますが、そのようなことは何も言いませんでした。

修理:

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

最後に、?貪欲修飾子を使用すると、驚きが生じる可能性があります (特に、1 つのパターンで複数の修飾子を使用する場合)。与えられた場合

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 に答える
0

()括弧と$1$22番目の括弧グループなど)を使用してテキストをキャプチャします。

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 に答える
0

ここから始めます。

if ($String =~ /hello (.*?) yesterday/i) {
    print $1;
}
于 2012-06-18T18:44:30.177 に答える