診断しようとしている非常にクレイジーな正規表現があります。また、非常に長いですが、次のスクリプトだけに短縮しました。 Strawberry Perl v5.26.2を使用して実行します。
use strict;
use warnings;
my $text = "M Y H A P P Y T E X T";
my $regex = '(?i)(?<!(Mon|Fri|Sun)day |August )abcd(?-i)';
if ($text =~ m/$regex/){
print "true\n";
}
else {
print "false\n";
}
これにより、「可変長の後読みが正規表現に実装されていません」というエラーが発生します。
いくつかの問題を解決できることを願っています。
(?i)
と(?-i)
の解釈方法がわかりません。 (?i)
を取り除くと、実際にエラーはなくなります。 Perlは正規表現のこの部分をどのように解釈しますか?最初の2文字は「オプションのリテラル括弧」と評価されますが、括弧はエスケープされず、その場合は閉じ括弧が一致しないため、別の構文エラーが発生します。私はあなたの問題をこれに減らしました:
my $text = 'M Y H A P P Y T E X T';
my $regex = '(?<!st)A';
print ($text =~ m/$regex/i ? "true\n" : "false\n");
/i
(大文字と小文字を区別しない)修飾子の存在と、 Typographic_ligature で置き換えることができる"ss"
や"st"
などの特定の文字の組み合わせの存在により可変長である(/August/i
は、たとえばAUGUST
(6文字)とaugust
(5文字、最後はU + FB06)の両方に一致します)。
ただし、/i
(大文字と小文字を区別しない)修飾子を削除すると、活版印刷の合字が一致しないため機能します。
解決策:aa
修飾子を使用します。つまり:
/(?<!st)A/iaa
または正規表現で:
my $text = 'M Y H A P P Y T E X T';
my $regex = '(?<!(Mon|Fri|Sun)day |August )abcd';
print ($text =~ m/$regex/iaa ? "true\n" : "false\n");
perlre から:
ASCIIと非ASCIIの一致(「\ N {KELVIN SIGN}」と「k」など)を禁止するには、「a」を2回指定します(例:
/aai
または/aia
)。 (最初の「a」の出現は\d
などを制限し、2番目の出現は「/ i」の制限を追加します。)ただし、ASCIIの範囲外のコードポイントは/i
マッチングのUnicodeルール。したがって、修飾子は実際にはASCIIだけに制限しません。 ASCIIと非ASCIIの混合を禁止します。
st
が合字になる可能性があるためです。同じことがfi
とff
にも起こります:
#!/usr/bin/Perl
use warnings;
use strict;
use utf8;
my $fi = 'fi';
print $fi =~ /fi/i;
fi|fi
のようなものを想像してください。実際、代替の長さは同じではありません。
(?i)
後読み後:
(?<!(Mon|Fri|Sun)day |August )(?i)abcd(?-i)
または
(?<!(Mon|Fri|Sun)day |August )(?i:abcd)
私にはそれはバグのようです。