もちろん、これは可能です。結局のところ、Perl正規表現について話しているのです。しかし、それはかなり醜いでしょう:
say "55336"=~m{(\d)\1(\d)\2(\d)(?(?{$1+1==$3})|(*F))}?"match":"fail";
またはきれいに印刷された:
say "55336" =~ m{ (\d)\1 (\d)\2 (\d)
(? (?{$1+1==$3}) # true-branch: nothing
|(*FAIL)
)
}x
? "match" : "fail";
これは何をしますか?通常のキャプチャで数字を収集します。最後に、if-elseパターンを使用します。
(? (CONDITION) TRUE | FALSE )
を使用して正規表現にコードを埋め込むことができます(?{ code })
。このコードの戻り値を条件として使用できます。((*FAIL)
short (*F)
:)動詞は、一致を失敗させます。(*PRUNE)
パターン全体が失敗するのではなく、ブランチのみが必要な場合に使用します。
埋め込みコードはデバッグにも最適です。ただし、古いperlsは、この正規表現コード内で正規表現を使用できません:-(
したがって、多くのものを照合し、パターン自体の内部で有効性をテストできます。ただし、次のようなパターンの外でそれを行う方がよい場合があります。
"string" =~ /regex/ and (conditions)
次に、メインパターンについて説明します(正しく解析したことN-3N-2N-1NNN+1N+2N+3
を願っています)。
my $super_regex = qr{
# N -3 N-2 N-1 N N N+1 N+2 N+3
(\d)-3\1-2\1-1\1\1(\d)(\d)(\d)
(?(?{$1==$2-1 and $1==$3-2 and $1==$4-3})|(*F))
}x;
say "4-34-24-144567" =~ $super_regex ? "match" : "fail";
またはあなたは意味しました
my $super_regex = qr{
#N-3 N-2 N-1 N N N+1 N+2 N+3
(\d)(\d)(\d) (\d)\4 (\d)(\d)(\d)
(? (?{$1==$4-3 and $2==$4-2 and $3==$4-1 and
$5==$4+1 and $6==$4+2 and $7==$4+3})|(*F))
}x;
say "123445678" =~ $super_regex ? "match" : "fail";
怖いのは、これらも機能することです(perl5.12で)。
コンストラクトを使用して、一致時にパターンの一部を生成することもでき(??{ code })
ます。このコードの戻り値は、パターンとして使用されます。
my $super_regex = qr{(\d)(??{$1+1})(??{$1+2})}x;
say "234"=~$super_regex ? "match":"fail"
等。ただし、この方法では読みやすさがさらに低下すると思います。
9つを超えるキャプチャが必要な場合は、名前付きキャプチャを使用できます。
(?<named>pattern) ... \k<named>
構成します。内容は%+
ハッシュでも利用できます。詳細については、perlvarを参照してください。
Perl正規表現の秘密をさらに掘り下げるために、 perlreを数回読むことをお勧めします。