ローカルにおいてある HTML ファイルを読み込ませて、<IMG SRC="sample.gif"> から sample.gif を取得します。
このsample.gifのMD5を取得し、たとえば MD5 が "abcd...xyz" であれば、
(ローカルの別フォルダ)/a/b/abcd...xyz.gif にコピーし、
元の参照を <IMG SRC="a/b/abcd...xyz.gif"> に変換するというスクリプトを書きたいと考えています。
HTML ファイルから sample.gif を取り出す方法、ファイルからMD5を取得する方法について教えていただけないでしょうか。
HTMLのパースなど調べたのですが、特定の属性を書き換える方法は
分かりませんでした。
よろしくお願いいたします。
No.1ベストアンサー
- 回答日時:
こんにちは、
書いてから気が付きましたが、画像を先にコピーして、
コピーした情報をハッシュとかに持っといて、その後、その情報を元に HTML を書き換えた方がいいかもですね。
以下のスクリプトは複数参照されている画像は何度もコピーされる事になりますし、エラーも完全無視です、ファイルのロックもしてません。
テストもろくにしてませんし、責任持てませんので、ご自分で書かれる際の参考程度にして下さい。
ファイルを読み込んで正規表現で置換してるだけです。
モジュールは perl5.8 なら多分標準だと思います。
md5 は http://search.cpan.org/~gaas/Digest-MD5-2.36/MD5 … を参考にしてみてください。
#! perl
use 5.008;
use strict;
use warnings;
use Digest::MD5;
use File::Copy;
main();
sub main {
#画像のコピー先ディレクトリ
my $path = './copy/';
local $/ = undef;
#同ディレクトリ内の拡張子が .html のファイル全て
for my $file ( glob('*.html') ) {
open my $fh, '+<', $file or next;
my $source = <$fh>;
$source =~ s{(<img [^>]* src=")([^"]+)}
{ $1 . rename_image( $2, $path ) }igesmx;
truncate $fh, 0;
seek $fh, 0, 0;
print {$fh} $source;
close $fh or next;
}
}
sub rename_image {
my( $img, $path ) = @_;
my( $name, $ext ) = $img =~ /^(.*)(\.\w+)$/;
my $new_name = $path . Digest::MD5::md5_hex($name) . $ext;
File::Copy::copy( $img, $new_name ) or return $img;
return $new_name;
}
参考URL:http://search.cpan.org/~gaas/Digest-MD5-2.36/MD5 …
ありがとうございます。
ソースまで提供していただき、大変助かります。
動作の確認をしましたが、希望している動作とは多少異なるようです。
・引数で読み込むhtmlファイルを指定したい
・フォルダの掘り方が違う
・フォルダがなければ作るようにしたい
・できれば、修正後のhtmlは別ファイルにしたい
いただいたソースで理解できているのはこんな感じです。
・open でファイルを開いて$sourceに入れ、
・正規表現で<img~src="..." の ... を取得し、
・rename_image でそのファイルのMD5を取得し、
・元のファイルのパスも変更する
で、自分で修正しようと思うのですが、やっぱり分かりません。
自分でperlを書いていたときは、open でファイルをオープンして、
while (<FH>) などで行ごとに処理してましたが、
提示していただいたソースではファイルごと$sourceに入れてるんですか??
s{..} の正規表現部分も )( の意味が分かりません。私が書くと
<img[^>]* src="([^"]+)
()でくくったら$1に入る?のかと思うのですが、残念ながら何もマッチしない・・・。
この s{...}{...}igesmx;
としている s って置換の関数?
perl って省略が多いせいか、調べても分からない部分が多くて・・。
いい参考サイトがあったら教えてください。
MD5についてはもう少し理解できてから拝見させていただきます。
No.3
- 回答日時:
>perl って省略が多いせいか、調べても分からない部分が多くて・・。
>いい参考サイトがあったら教えてください。
どの言語でもそうですが、サイトでチョコチョコ調べるというよりは最初はドンと本で勉強した方がいいと思いますよ。
http://www.amazon.co.jp/gp/product/4774108170/re …
http://www.amazon.co.jp/%E5%88%9D%E3%82%81%E3%81 …
No.2
- 回答日時:
こんにちは、
> ・引数で読み込むhtmlファイルを指定したい
コマンドプロンプトから perl xxxx.pl ファイル名
とかやって、スクリプト内で、$ARGV[0] を参照すれば良いと思います。
> ・フォルダの掘り方が違う
これも引数とかで指定してやれば良いと思います。
> ・フォルダがなければ作るようにしたい
ファイルテスト演算子を使って判定して、なければ、mkdir すればよいとおもいます。
> ・できれば、修正後のhtmlは別ファイルにしたい
ファイルのオープンを読み込みオープンにして、
任意のファイル名で新規書き出ししてください。
> いただいたソースで理解できているのはこんな感じです。
> ・open でファイルを開いて$sourceに入れ、
> ・正規表現で<img~src="..." の ... を取得し、
> ・rename_image でそのファイルのMD5を取得し、
> ・元のファイルのパスも変更する
その通りです。
> で、自分で修正しようと思うのですが、やっぱり分かりません。
> 自分でperlを書いていたときは、open でファイルをオープンして、
> while (<FH>) などで行ごとに処理してましたが、
> 提示していただいたソースではファイルごと$sourceに入れてるんですか??
です。
local $/ = undef;
で、ファイルを丸呑みするようになります。
> s{..} の正規表現部分も )( の意味が分かりません。私が書くと
> <img[^>]* src="([^"]+)
> ()でくくったら$1に入る?のかと思うのですが、残念ながら何もマッチしない・・・。
> この s{...}{...}igesmx;
> としている s って置換の関数?
$str =~ s/hoge/fuga/;
で、$str 内の 'hoge' を 'fuga' に置換します。
正規表現はあまり得意じゃないので、アレなんですが…
正規表現内で()で括ると後方参照できるようになります。
最初の括弧でキャプチャした文字列を$1次の括弧が$2…てな感じです。
で、イメージタグの src 属性のファイル名の直前までの文字列を$1にキャプチャして、
$2 にファイル名をキャプチャしているつもりです。
で、それをサブルーチンに渡して、コピーできたら、新しいファイル名を返してくるので、
そのファイル名とさっきキャプチャしたファイル名直前までの文字列を結合して、
マッチした全体と置換しているつもりです。
正規表現に e オプションをつけると、perl スクリプトとして評価されます。
正規表現のオプションに関しては、google 先生に尋ねてください。
勝手な事しまして、かえって混乱させてしまったようですね、すみませんです。
通常、ファイルは1行ずつ処理した方が少ないメモリで処理できて良いのでしょうが、
ローカルで行う処理なら、丸呑みも良いと思います。
その為のモジュールもありますので、時間が合ったら調べてみられたら良いかもです。
ありがとうございました!
ちょっと分からないところが多かったのですが、
じっくり調べながらソースを読み返してみると、
ほぼ理解でき、目的のものも作ることができました。
> $str =~ s/hoge/fuga/;
これは知ってたのですが、
$str =~ s{hoge}{fuga};
と書いてもよいんですね。別の関数かなんかなのかと思ってしまいました。
扱ってるhtml ファイルはサイズも大して大きいものがないので、
ファイルを丸ごと処理できる方法を教えていただき、とても助かりました。
複数行にまたがるタグも多いのですが、その置換もできました。
本当にありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI htmlからパラメータで、cgiに渡したい。 1 2023/02/06 16:15
- HTML・CSS img と p を縦中央に配置したいのですがうまくいきません。 2 2023/01/12 14:38
- HTML・CSS CSSが効かずどのように指定すれば良いか分からないのでアドバイスお願い致します 2 2023/06/07 12:25
- JavaScript jQueryで同じクラス名のものを別物として扱いたい 1 2022/06/17 14:14
- PHP PHP・Wordpress preg_replaceを条件分岐で処理させる方法が知りたい 1 2023/05/01 14:25
- PHP PHP echo バックスラッシュの使い方 img要素 2 2023/01/08 22:46
- Ameba(アメーバブログ) アメブロは、HTMLのタグの入力を許さないブログ・サイトですか? 1 2023/06/18 18:48
- ホームページ作成・プログラミング アメーバ・ブログは"HTMLタグ"を許可してないのですか? 2 2023/06/17 21:08
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlをバージョンアップしたら...
-
INDIRECT 横に再度抽出したい
-
Strawberry Perl for Windows ...
-
openした後、closeしないでプロ...
-
テキストファイルで提出とは?
-
Perlのエラーについてご教授く...
-
perlのrequireの動き方について...
-
Perl の外部モジュールの利用方法
-
Windows10においての『Perl』の...
-
Perlで特定文字列から特定文字...
-
Perlでsprintf("%02d",$month)...
-
フローチャート 九九
-
perl LWPでURLにアクセスした時...
-
Perlで、「が」を、「...
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
INDIRECT 横に再度抽出したい
-
perlをバージョンアップしたら...
-
openした後、closeしないでプロ...
-
Perlで特定文字列から特定文字...
-
Wallpaper Engineでおすすめの...
-
Perlのエラーについてご教授く...
-
アルファベットに付いて質問し...
-
Strawberry Perl for Windows ...
-
bashスクリプト
-
テキストファイルで提出とは?
-
Perl の外部モジュールの利用方法
-
#!/usr/bin/perlで書きだしたCG...
-
Windows10においての『Perl』の...
-
perlのflock関数でロックをかけ...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlのrequireの動き方について...
-
画像が表示でnull; this.src
-
ターミナルで特定の文字と文字...
-
英数文字列のうちの数値を4桁に...
おすすめ情報