サブパターン プレースホルダー '$1' を変数の置換演算子 's///' に渡すときに、正しくクォートできない問題があります。誰かがこれに光を当てて、私が間違っていることを教えてもらえますか?
MS Word ドキュメントのセットを HTML ファイルにエクスポートしています。これは、ファイルに多くの相互参照が含まれており、機能し続けるにはこれらを修正する必要があることを除いて、多かれ少なかれ問題なく機能します。エクスポートされた参照は 'href="../../somefilename.docx"' の形式であり、元の Word ファイルの代わりにエクスポートされた html ファイルを参照するには、これらを 'href="somefilename.htm"' に変更する必要があります。 .
たとえば、ファイル test.htm の例は次のようになります。
<html>
<body>
<a href="../../filename1.docx" />
<a href="../../filename2.docx" />
<a href="../../filename3.docx" />
<a href="../../filename4.docx" />
</body>
</html>
プログラムの実行により、次の結果が得られます。
<html>
<body>
<a href="filename1.htm" />
<a href="filename2.htm" />
<a href="filename3.htm" />
<a href="filename4.htm" />
</body>
</html>
その仕事をするために、小さな Perl プログラム 'ReplaceURLs' を書きました。パターンと置換式を「ハードコード」すると (つまり、パターンを s/.../.../g ステートメントに直接配置すると)、正常に動作します - バリアント 1 を参照してください。これらの式を引数 (つまり、s/$pattern/$subst/g) として渡せるようにしたいのですが、うまくいきません。変数でパターンを渡すことができます - バリアント 2 を参照してください。ただし、サブパターン参照 $1 を含む置換値は渡せません。バリアント 3 では、何らかの理由で置換値の $1 がサブパターン マーカーとして認識されず、リテラル '$' として扱われます。
#!/usr/bin/perl
$debug = TRUE;
$tgtfilename = $ARGV[0] || die("usage: ReplaceURLs.pl <filename> <url-pattern> <url-substvalue>");
$urlpattern = $ARGV[1] || "href=\"\.\./\.\./(.*)\.docx\""; # href="../../(filename).docx';
$urlsubstval = $ARGV[2] || "href=\"\$1.htm\""; # href="$1.htm" --> href="(filename).htm";
print "replacing all occurences of pattern '$urlpattern' in file '$tgtfilename' with '$urlsubstval':\n";
# open & read $tgtfilename
open($ifh, '<', $tgtfilename) || die "unable to open $tgtfilename for reading: $!";
@slurp = <$ifh>;
$oldstring = "@slurp";
close($ifh) || die "can't close file $tgtfilename: $!";
if ($debug) { print $oldstring,"\n"; }
# look for $urlpattern and replace it with $urlsubstval:
# variant 1: works
#($newstring = $oldstring) =~ s!href=\"\.\./\.\./(.*)\.docx\"!href=\"$1.htm\"!g;
# variant 2: works
#($newstring = $oldstring) =~ s!$urlpattern!href=\"$1.htm\"!g;
# variant : does not work - why?
($newstring = $oldstring) =~ s/$urlpattern/$urlsubstval/g;
# save file
#open($ofh, '>', $tgtfilename) || die "unable to re-open $tgtfilename for writing";
#print $ofh $newstring,"\n";
#close($ofh) || die "can't close file $tgtfilename: $!";
# done
if ($debug) { print "result of replacement:","\n", $newstring,"\n"; } else { print "done."; }
__END__
「perl ReplaceURLs.pl test.htm」を使用してこれを実行すると、常に次のようになります。
<html>
<body>
<a href="$1.htm" />
<a href="$1.htm" />
<a href="$1.htm" />
<a href="$1.htm" />
</body>
</html>
望ましい結果の代わりに。これを機能させるには、$urlsubstval の '$1' をどのように引用またはエスケープする必要がありますか?
M.