質問: str_replace(array('\'', '"'), '', $str); しかし、削除してはならないものまで削除してしまいます。 (id="hoge hoge2"のように空白を挟んだものや、マルチバイト文字を用いたもの、URL記載されているものなど) ダブルクオーテーションを削除したところで大した縮小は望めないとは理解していますが、もし上手いやり方があればご教授願いたく思います。 よろしくお願い致します。
回答: 一応書いておくべきだと思うので書いてます、必要に応じて読んでください =================================== 優先順位を大幅に間違えてるように思えます。 そもそも何故そんなことになってしまっているのかを伺ってもよろしいですか? 上司の指示?サーバーの負荷が重くなった?コストダウン? (Amazonリンク) ハイパフォーマンスWebサイト ―高速サイトを実現する14のルール この辺を全てやり尽くした上でのダブルクォート削減ならば良いのですが... 代表的な質問事項を上げておきます。 * 誰がHTMLの妥当性をチェックするの? - メリットに対してのリスクが高すぎる - 例えば回答者が作ったロジックに抜け漏れがあって潜在的な売上を逃した場合、誰の責任か? - 仮に私が上司で部下が同じ事をやろうとしていれば、リスクや責任を回避するためにやめるよう指示する * gzip圧縮はかけた? - テキストファイルならば圧縮後のファイルサイズは25%程度になる - ダブルクォート2つ減らしても0.5バイトの削減程度の効果しか得られない * 画像ファイルは全て最適化済? - 画像の最適化で数10~100KB単位でファイルサイズが変わる - どんなしょぼい1ドットの画像でも1KB - デザイン面で画像を減らしてCSSで頑張れないかを検討するほうが先 * CSSやJavaScriptファイルも最適化済? - こちらは静的サイトジェネレーター等のツールで一撃 * なぜWordpress? - WordpressはWebサイトを楽して作るためのもので、動作自体はかなり遅い - 静的ファイルで持ったり、そもそもPHPやApacheを手放す事を検討する話にもなりそう 本題 === > > しかし、削除してはならないものまで削除してしまいます。 > > (id="hoge hoge2"のように空白を挟んだものや、マルチバイト文字を用いたもの、URL記載されているものなど) > > > W3C HTML5仕様書(日本語訳) 1.9 HTMLの簡単な手引きによると、NGな要素は以下 ``` 空白文字または任意の" ' ` = < > ``` つまりマルチバイトやリンクはあっても大丈夫ですかね。 (IEでは~...Firefoxでは~...等の例外はあるかと思いますので、この辺の動作検証はお願いします) 本来ならば手っ取り早くこのようにしたいところです。(luckerさんの回答のパクリ) ``` $str = preg_replace(['/\="([a-zA-Z0-9\-_]+)"/', "/\='([a-zA-Z0-9\-_]+)'/"], "=$1", $str); ``` しかし、ScriptやStyle、テキストノード内の文字列も殺し始めるのでちゃんとタグの中身ですよということを確認する必要があります。 正規表現でその辺を証明しつつ作る方法はあるかと思いますが... なので今回はタグの中身ということを確認しつつ、 `$target_attributes`に`=`の位置が全て入った配列を突っ込むコードを書いてみました。 ※未テストなのでこのままだと多分動きません。 もっとスマートな書き方は色々出来ますが、それなりに高速に動作するはずです。 もしこの続きからされるのでしたら使ってみてください。 ``` $html = $str; $target_attributes = array(); $offset = 0; while (($elm_start = mb_strpos($html, '<', $offset)) !== false) { // 1文字目が/なら終了タグなので飛ばす if ((mb_strpos($html, '/', $elm_start + 1) === ($elm_start + 1)) { $offset = $elm_start + 1; continue; } //TODO: 必要があればこの辺にScriptタグ内でないことを証明する // タグの終了文字を控えておく if (($elm_end = mb_strpos($html, '>', $elm_start + 1)) === false) break; $elm_offset = $elm_start + 1; while (($elm_offset = mb_strpos($html, '=', $elm_offset)) !== false) { if ($elm_offset < $elm_end) break; $target_attributes[] = $elm_offset++; } } // 多分$htmlを破壊的に書き換えて行くことになるので、$attributesを降順にしておく rsort($target_attributes); ```