次のようなコードがあります。
s/(["\'])(?:\\?+.)*?\1/(my $x = $&) =~ s|^(["\'])(.*src=)([\'"])\/|$1$2$3$1.\\$baseUrl.$1\/|g;$x/ge
最後のビットを無視して (問題が発生した部分だけを残して)、コードは次のようになります。
s/(["\'])(?:\\?+.)*?\1/replace-text-here/g
両方を使用してみましたが、同じ問題が発生します。つまり、 g 修飾子を使用しているにもかかわらず、この正規表現は最初に出現したものにのみ一致して置き換えます。これが Perl のバグである場合はわかりませんが、2 つの引用符の間のすべてに一致する正規表現を使用し、エスケープされた引用符も処理し、このブログ投稿に従っていました。私の目には、その正規表現は 2 つの引用符の間のすべてに一致し、それを置き換えてから、g 修飾子のために、このパターンの別のインスタンスを見つけようとするはずです。
ちょっとした背景情報として、私はバージョン宣言を使用しておらず、厳格な警告をオンにしていますが、警告は表示されていません。私のスクリプトは、ファイル全体をスカラー (改行を含む) に読み取り、正規表現はそのスカラーで直接動作します。各行で個別に機能するようです-1行で複数回ではありません。Cygwin 64 ビットで動作する Perl バージョン 5.14.2。Cygwin (または Perl ポート) が何かを台無しにしている可能性がありますが、私はそれを疑っています。
また、そのブログ投稿の別の例を試してみました。アトミック グループと所有量指定子を同等のコードに置き換えましたが、それらの機能はありませんでしたが、この問題は依然として私を悩ませていました。
例:
<?php echo ($watched_dir->getExistsFlag())?"":"<span class='ui-icon-alert'><img src='/css/images/warning-icon.png'></span>"?>
Should become (with the shortened regex):
<?php echo ($watched_dir->getExistsFlag())?replace-text-here:replace-text-here?>
Yet it only becomes:
<?php echo ($watched_dir->getExistsFlag())?replace-text-here:"<span class='ui-icon-alert'><img src='/css/images/warning-icon.png'></span>"?>
<?php echo ($sub->getTarget() != "")?"target=\"".$sub->getTarget()."\"":""; ?>
Should become:
<?php echo ($sub->getTarget() != replace-text-here)?replace-text-here.$sub->getTarget().replace-text-here:replace-text-here; ?>
And as above, only the first occurrence is changed.
(そして、はい、これが何らかの形で発生することを認識しています-HTML/PHPの解析に正規表現を使用しないでください。しかし、この場合、コンテキストを探しているのではなく、探しているので、正規表現の方が適切だと思います文字列 (引用符内のすべて) に対して、その文字列に対して操作を実行する - これは正規表現です)。
これらの正規表現は eval 関数で実行され、実際の正規表現は一重引用符で囲まれた文字列でエンコードされます (これが一重引用符がエスケープされる理由です)。私の悪いプログラミングを除外するために、提示されたソリューションを直接試します。
編集: 要求に応じて、問題を提示する短いスクリプト:
#!/usr/bin/perl -w
use strict;
my $data = "this is the first line, where nothing much happens
but on the second line \"we suddenly have some double quotes\"
and on the third line there are 'single quotes'
but the fourth line has \"double quotes\" AND 'single quotes', but also another \"double quote\"
the fifth line has the interesting one - \"double quoted string 'with embedded singles' AND \\\"escaped doubles\\\"\"
and the sixth is just to say - we need a new line at the end to simulate a properly structured file
";
my $regex = 's/(["\'])(?:\\?+.)*?\1/replaced!/g';
my $regex2 = 's/([\'"]).*?\1/replaced2!/g';
print $data."\n";
$_ = $data; # to make the regex operate on $_, as per the original script
eval($regex);
print $_."\n";
$_ = $data;
eval($regex2);
print $_; # just an example of an eval, but without the fancy possessive quantifiers
これにより、次の出力が生成されます。
this is the first line, where nothing much happens
but on the second line "we suddenly have some double quotes"
and on the third line there are 'single quotes'
but the fourth line has "double quotes" AND 'single quotes', but also another "double quote"
the fifth line has the interesting one - "double quoted string 'with embedded singles' AND \"escaped doubles\""
and the sixth is just to say - we need a new line at the end to simulate a properly structured file
this is the first line, where nothing much happens
but on the second line "we suddenly have some double quotes"
and on the third line there are 'single quotes'
but the fourth line has "double quotes" AND 'single quotes', but also another "double quote"
the fifth line has the interesting one - "double quoted string 'with embedded singles' AND \"escaped doubles\replaced!
and the sixth is just to say - we need a new line at the end to simulate a properly structured file
this is the first line, where nothing much happens
but on the second line replaced2!
and on the third line there are replaced2!
but the fourth line has replaced2! AND replaced2!, but also another replaced2!
the fifth line has the interesting one - replaced2!escaped doubles\replaced2!
and the sixth is just to say - we need a new line at the end to simulate a properly structured file