人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPでの質問です。
HTMLのデータを文字列として保持していて、これを使った処理を行おうとしています。
しかし、このときタグ内の属性値が""で囲まれていない場合があります。

例)
<img id=image_1 style="border-width: 1px; border-style: solid" src="header.gif" height=100 width=300/>

↑こんな風に、囲まれてたり囲まれて無かったりとバラバラです。

このような状況のとき、すべての属性値を""で囲むように変換してあげたいのですが、どのような処理を行えば良いか、知恵をお貸し下さい。

正規表現での置換を行えば良いかと考えたのですが、自分では上手くできませんでした。

よろしくお願いします。

●質問者: sei4u
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:HTML PHP タグ データ 属性
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ●
●40ポイント
<?php

$str_html = '<img id=image_1 style="border-width: 1px; border-style: solid" src="header.gif" height=100 width=300/>';

$pattern = '/(?:(=)\s*([^"]))(.*?)(?:([^:;"])(\s+|\/))/';
$replacement = '$1"$2$3$4"$5';

echo preg_replace($pattern, $replacement, $str_html);

?>

とりあえず、なソースですが参考になれば幸いです。

(シングルクォートで属性を囲んでいる場合などは考慮していません。)

◎質問者からの返答

ありがとうございます!

いい感じと思ったのですが、


$str_html = '<img id=image_1 style="border-width: 1px; border-style: solid" src="header.gif" height=100 width=300/>ABC=DEF<br />';


などとしたら悲しい感じになっちゃいました。

先にタグの部分だけを取り出すようにした方が良いのでしょうか。。。


2 ●
●40ポイント

こんな感じでいかがでしょう。

<?php

$str_html = '<img id=image_1 style="border-width: 1px; border-style: solid" src="header.gif" height=100 width=300/>ABC=DEF<br />';

while (1) {
 $pattern = '/(<[^>]*?)(?:(=)\s*?([^"]))(.*?)(?:([^:;"])(\s+|\/))(.*?>)/';
 $replacement = '$1$2"$3$4$5"$6$7';
 if ( $str_html != preg_replace($pattern, $replacement, $str_html) ) {
 $str_html = preg_replace($pattern, $replacement, $str_html);
 } else {
 break;
 }
}

print $str_html;

?>

何度も比較するのであまり速度が出ません。

また、どんなHTMLがあり得るのか分からないので、細かい部分が上手くいかないこともあると思います。

これを参考にカスタマイズしてみてはいかがでしょうか。

(もっと良いやり方があったと思うのですが、手元にフクロウ本がないので思い出せません…。有識者がフォローしてくれますように。)

少しでも参考になれば幸いです。

◎質問者からの返答

何度もありがとうございます><;


今のところ思ったとおりに動作してます……感激しました。


フクロウ本というのは、『詳説 正規表現』の事ですよね?

やはりちゃんと読んでおくべきですよね。。。

しっかり学んで対応できるようにしたいと思います。


本当にありがとうございます!


3 ● tobeoscontinue
●60ポイント
<?php
function quotelint($data)
{
 $split = array_chunk(preg_split("/<(.+?)>/", $data, -1, PREG_SPLIT_DELIM_CAPTURE), 2);
 $contents = '';
 foreach ($split as $tags) {
 list($pre, $tag) = $tags;
 $contents .= $pre;
 if (!empty($tag)) {
 $pattern = "/ (\w+?)='*([\w\d:]+)'*/";
 $contents .= "<".preg_replace($pattern, ' $1="$2"', $tag).">";
 } }

 return $contents;
}

$str_html = '<img style="border-width: 1px; border-style: solid" src="header.gif"'." height='100'". ' width=300/>ABC=DEF<br />';

echo quotelint($str_html);

?>

既に解決済みですがやってみました。


preg_split()でタグの外と中に分けます。

次にタグの中($tag)だけについてpreg_replace()で置換します。

$contentsへ結合していきreturnで返します。

name=valueの

nameは単語構成文字(\w)だけ、

valueは単語構成文字(\w)と数字(\d)と:だけにしているので不都合があるかも知りません。

◎質問者からの返答

ありがとうございます!

なるほどなるほど。丁寧なご説明まで頂いて、とてもわかりやすいです。

array_chunkってこうやって使えるのか……


必要に応じていろいろと調整がしやすそうです。

本当に助かります。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ