PHPでの質問です。

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

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

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

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

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

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 登録:2006/12/01 09:45:14
  • 終了:2006/12/04 09:25:11

回答(3件)

id:bonlife No.1

回答回数421ベストアンサー獲得回数752006/12/01 10:21:02

ポイント40pt
<?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);

?>

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

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

id:sei4u

ありがとうございます!

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


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


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

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

2006/12/01 11:35:13
id:bonlife No.2

回答回数421ベストアンサー獲得回数752006/12/01 12:53:37

ポイント40pt

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

<?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があり得るのか分からないので、細かい部分が上手くいかないこともあると思います。

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

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

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

id:sei4u

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


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


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

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

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


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

2006/12/01 14:03:14
id:tobeoscontinue No.3

tobeoscontinue回答回数214ベストアンサー獲得回数542006/12/01 19:12:00

ポイント60pt
<?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)と:だけにしているので不都合があるかも知りません。

id:sei4u

ありがとうございます!

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

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


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

本当に助かります。

2006/12/02 13:30:10
  • id:bonlife
    補足です。

    フクロウ本はsei4uさんのコメントにある通り「詳説 正規表現」のことです。
    私もまだ読んでいる途中なのですが、8月に発売された3rd Edition(英語版)ではPHP用に章が追加されています。
    http://www.oreilly.com/catalog/regex3/
    正規表現って理解しているようで、実は正しく理解できていなかったりすることが多いので、一度勉強しておくと良いような気がします。

    参考になれば幸いです。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません