###HTMLコード内の正規表現によるスタイル除去で特定のスタイルを残す方法
PHP上で文字列として保持しているHTMLコード内の、
###現在作成してみた正規表現パターン
php
1$body = preg_replace('/<td ("[^"]*"|\'[^\']*\'|[^\'">])*>/', '<td>', $body);
この正規表現でTDタグのスタイル要素類全てを削除することができたのですが、rowspanとcolspanを残す。というのがどうしてもできずという状況です。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
こういう複雑なのは小さくわかりやすい要素から順番に考えていくのが常套です。
まず、タグの正規表現は「<」から始まり「>」で終わるため
例としてhoge要素のタグを考えると
php
1’/<hoge [^>]*>/’
それでとりあえず属性piyoをサーチするということで
php
1’/<hoge [^>]*(piyo=((\'[^\'>]*\')|("[^">]*")))[^>]*>/’ 2piyoは\1で回収
※piyoの値がエスケープを使ったクォーテーションを含む文字列のときはこれではダメですが複雑になるのでここでは無視してます。
これをベースに
hoge = td
piyo = rowpsan|colspan
を考えると
php
1'/<td [^>]*((row|col)span=((\'[^\'>]*\')|("[^">]*")))[^>]*>/'
そして、
0. tdはヘッダーであるthの場合もある
0. rowspan/colspanの値は数字
0. タグは大文字のときもある
を考えてpreg_replaceの関数に入れると
php
1$body = preg_replace('/<(td|th) [^>]*((row|col)span=("\d+"|\'\d+\'))[^>]*>/i', '<\1 \2>', $body);
となります。
完成!ヽ(=´▽`=)ノ
↑うそでした
↓修正
colspanとrowspanをそれぞれ保つ場合もあることを失念してました。
なので本当は
php
1$body = preg_replace('/<(td|th) [^>]*?((?:row|col)span=(?:"\d+"|\'\d+\'))(?:[^>]*((row|col)span=("\d+"|\'\d+\')))?[^>]*>/i', '<\1 \2 \3>', $body);
です。
ちょっと解説する量が多くなるので解説はごめんなさい。パズルみたいに考えてみてください。
あと、これの後に
php
1$body = preg_replace('/<(td|th) +>/i','<td>',$body)
を更に入れておくと吐き出されるHTMLソースが綺麗になります。
投稿2016/05/30 13:14
編集2016/05/30 13:35総合スコア1895
0
あまり綺麗にいかなかったのですが、こんな感じでどうでしょう?
PHP
1$pattern = '/<td(( rowspan.*?(["\']).*?\3)|( colspan.*?(["\']).*?\5)|.)*?>/'; 2 3$str = "<td colspan='2' rowspan='\"3\"' aaa='123'>"; 4echo preg_replace($pattern, '<td\2\4>', $str); 5//<td rowspan='"3"' colspan='2'> シングル&ダブルクオートのネストは多分OK 6 7$str = "<td colspan='2'rowspan='3' aaa='123'>"; 8echo preg_replace($pattern, '<td\2\4>', $str); 9//<td colspan='2'> 先頭にスペースが無いと無視 10 11$str = "<td colspan='2' rowspan='3' aaa='123' rowspan='5'>"; 12echo preg_replace($pattern, '<td\2\4>', $str); 13//<td rowspan='5' colspan='2'> 同じ属性が2つある場合は後方優先
投稿2016/05/30 12:13
編集2016/05/30 14:23総合スコア2068
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
あんまり複雑な条件を正規表現一発で何とかしようとするのはデバッグ等の面で割と大変なので、
ちょっと方向性を変えて単純化するという手もあります。
例えば
-
- HTMLを改行や閉じタグ単位でexplode()等で分割して配列に格納する
-
- 配列をforeachで走査する
-
- (配列の要素が<td>を含んでるか確認し、含んでなかったら次の要素に飛ぶ)
-
- 配列の要素一つ一つをpreg_match()で<td>タグのcolspan,rowspanを抜き出して変数に格納する
-
- 格納した変数を今出来ているpreg_replaceの'<td>'に組み合わせて置換する
-
- 出来上がった配列をimplode()で文字列に連結する
みたいにすれば出来るでしょうし、
もっとスマートに処理するなら
PHP HTML パーサで検索
して、HTMLを文字列では無くオブジェクトとして扱い、tdオブジェクトの要素を操作して必要な属性だけ残す。という事が出来るようになれば、今後別の要素に別の操作をしたい時にでもあんまり悩まずに色々出来るようにまります。
投稿2016/05/30 12:10
総合スコア18709
0
もっとクレバーなやり方が有るとは思いますが、<td>
を拾ってその中の必要な項目(rowspanとcolspan)を拾って結合することで実現できると思います。
PHP
1$body = preg_replace_callback( 2 '/<td[^>]*>/' 3 , function ( $tds ) { // PHP 5.3+ 4 preg_match_all( "/(\s(?:col|row)span=(?:\"[^\"]*\"|\'[^\']*\'))/i", $tds[ 0 ], $match ); 5 return '<td'.implode( '', $match[ 0 ] ).'>'; 6 } 7 , $body 8); 9echo $body;
投稿2016/05/30 12:14
総合スコア69364
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/05/31 02:42