完璧に機能しているようです!
ここにヒントがあります: Perl 変数$`、$&、およびを使用してください$'。これらの変数は、一致前の文字列の一部、一致したもの、および一致した後の文字列を示す特別な正規表現変数です。
サンプルプログラムは次のとおりです。
#! /usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use Scalar::Util;
my @list = ("1", "2", "123");
foreach my $string (@list) {
    if ($string =~ /\d{1,2}?/) {
        say qq(We have a match for "string"!);
        say qq("$`"  "$&"  "$'");
    }
    else {
        say "No match makes David Sad";
    }
}
出力は次のようになります。
We have a match for "1"!
""  "1"  ""
We have a match for "2"!
""  "2"  ""
We have a match for "123"!
""  "1"  "23"
これにより、文字列が 3 つのセクションに分割されます。正規表現が一致する前の文字列のセクション、正規表現が一致する文字列のセクション、正規表現が一致した後の文字列のセクションです。
いずれの場合も、正規表現は文字列の先頭から一致するため、事前一致はありませんでした。\d{1,2}?また、 が 2 桁に一致した可能性がある場合でも、それぞれ 1 桁に一致することがわかり123ます。なんで?一致指定子の末尾にある疑問符は、正規表現が貪欲ではないことを示しているためです。この場合、1 つまたは 2 つの文字に一致するように正規表現を指定します。いいですね、それは 1 つに一致します。疑問符を削除すると、最後の行は次のようになります。
We have a match for "123"!
""  "12"  "3"
3 桁以上ではなく 1 桁または 2 桁で一致させたい場合は、文字列の 1 桁または 2 桁の前後の部分を指定する必要があります。このようなもの:
/\D\d{1,2}\D/
これは文字列と一致しますが、一致foo12barしませんfoo123bar。しかし、文字列が の場合は12どうでしょうか? その場合、1 文字または 2 文字が一致する前に文字列の先頭または非数字があり、末尾に非数字または文字列の末尾があると言いたいです。 1 文字または 2 文字の一致:
/(\D|^)\d{1,2}(/D|$)/
簡単な説明:
- (\D|^): 数字以外または文字列の先頭 (- ^アンカー)
- d{1,2}:1桁または2桁
- (\D|$): 数字以外または文字列の末尾 (- $アンカー)
さて、これは に一致しますが には一致し12ません。123また、 and には一致foo12しますが、 orには一致しfoo12barません。foo123foo123bar
1 桁または 2 桁の数字を探すだけで、アンカーを指定できます。
/^\d{1,2}$/;
これは , に一致しますが、 orには一致1し12ません。foo12123
主なことは、、、および変数を使用して$`、正規表現が何に一致しているか、および一致の前後に何があるかを正確に確認できるようにすることです。$&$'