🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

1回答

1421閲覧

正規表現のネストがうまくいかない

ippya

総合スコア31

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2019/12/08 11:51

編集2019/12/08 13:22

独自形式の文字列を、htmlタグに変換する処理を行っています。

例えば、以下の文字列に対し、

PHP

1$str = "{img:sample1.jpg}";

以下の処理を行い、

PHP

1while( preg_match('/{([^{}]+)}/', $str, $match) ){ 2 list($key, $p1, $p2) = explode(':', $match[1]); 3 switch($key){ 4 case 'img': 5 $v = '<img src="'.$p1.'">'; 6 $str = str_replace($match[0], $v, $str); 7 break; 8 case 'tr': 9 $v = '<tr><th>'.$p1.'</th><td>'.$p2.'</td></tr>'; 10 $str = str_replace($match[0], $v, $str); 11 break; 12 } 13}

これは、以下のように期待通りに変換されます。

HTML

1<img src="sample.jpg">

一応、{} をネストできるようにしたつもりですので

PHP

1$str = '<table>' 2 . '{tr:サンプル1:{img:sample1.jpg}}' 3 . '{tr:サンプル2:{img:sample2.jpg}}' 4 . '</table>';

を処理すれば、以下のようになることを期待していますが、

HTML

1<table> 2<tr><th>サンプル1</th><td><img src="sample1.jpg"></td></tr> 3<tr><th>サンプル2</th><td><img src="sample2.jpg"></td></tr> 4</table>

以下のようになってしまいます。

HTML

1<table> 2<tr></tr> 3<tr></tr> 4</table>

どこが間違っているのかがわからず困っています。
間違っている点をご指摘いただければありがたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/12/08 11:55

の前に > : そもそもこのコード、ポツンとある↑でエラー出てますよ。
ippya

2019/12/08 13:15

ごめんなさい。 「他にも同じような処理がある」という意味で、省略したつもりでした。 (途中省略)に変更します。
m.ts10806

2019/12/08 13:16

エラーで困っていないのでしたらエラーが出ないコードをご提示ください。 あまり省略されすぎると再現確認できないので、半端に省略するくらいなら改めて再現できる最小構成のコードを組んでご提示ください。
ippya

2019/12/08 13:23

省略をなくしました。
otn

2019/12/08 15:29

> 一応、{} をネストできるようにしたつもりですので ネスト化前と間違えてコピペしていませんか?
otn

2019/12/09 01:06

ああ、失礼しました。正規表現で再帰をやるんじゃなくて、ループで再帰を処理しているんですね。 PHP 7.3.12 ではうまくいきました。
ippya

2019/12/09 01:20

PHP 7.3.12 ではうまくいくんですね。検証ありがとうございました。^^ こちらは PHP 7.3.9 までしか利用できない環境です。 やはり PHPのバージョンの問題なんですかね。
mix-peach

2019/12/09 02:01

7.2.17と、7.3.8で動作確認をしましたが、どちらも期待通りの正しい結果になりましたので、バージョン差異に問題はなく、提示されたコード以外に原因があるのかもしれないなと思いました。 お手元で現象が確認できるコードを分割せずに、「独自形式の文字列の定義」「正規表現によるHTMLへの置換処理」「画面に出力」までの通したコードでご提示いただけると良いかもしれません。
yambejp

2019/12/09 02:22

正規表現うんぬんよりも、jsonなどもっと効率的なデータの持ち方にすれば 無駄に悩む必要はないと思いますが・・・
otn

2019/12/09 02:22

あ、もっと古いバージョン(5とか)なのかと思っていました。mix-peachさんの通り、バージョンの問題ではなさそうです。
ippya

2019/12/09 03:09

提示させていただいた内容を、そのまま実行したら、皆さんおっしゃるように、期待通りの結果になりました。 元々のコードは、定義部分を json 化しており、変換処理を汎用化しようとして、かなり長文化しているため、全文を掲載するには無理がありますので、要点を提示したつもりでしたが、その部分には問題ではなかったようです。 他の部分を見直します。 みなさん、お騒がせしました。申し訳ありません。
otn

2019/12/09 12:55

長いコードは、抜粋して、実行して、解決したい現象が出ることを確認してから、コピペしましょう。
kyoya0819

2019/12/10 12:05

ippyaさん 解決しましたら下のフォームに解決方法を入力いただき自己解決とすることで同じ悩みを待っている方が迅速に的確に解を得られやすくなります。 よろしくお願いいたします。
guest

回答1

0

自己解決

表題に「正規表現のネストがうまくいかない」と書きましたが、
正規表現とは関係ない、私の ミス による勘違いでした。

PHP

1$str = '<table>' 2 . '{tr:サンプル1;{img:sample1.jpg:200px:150px}}' 3 . '{tr:サンプル2;{img:sample2.jpg}}' 4 . '</table>'; 5 6while( preg_match('/{([^{}]+)}/', $str, $match) ){ 7 list($key, $other) = explode(':', $match[1], 2); 8 $v = ''; 9 switch($key){ 10 case 'img': 11 list($src, $w, $h) = explode(':', $other); 12 $s = []; 13 if( $w!="" ) $s[] = 'width:'.$w; // *****ミス***** 14 if( $h!="" ) $s[] = 'height:'.$h; // *****ミス***** 15 $style = (count($s)>0) ? ' style="'.implode('; ', $s).'"' : ''; 16 $v = '<img src="'.$src.'"'.$style.'>'; 17 break; 18 case 'tr': 19 list($text, $cls) = explode(':', $other); 20 $d = explode(';', $text); 21 $cols = ''; 22 foreach( $d, $v1 ){ 23 $cols .= '<td>'.$v1.'</td>'; 24 } 25 $v = '<tr>'.$cols.'</tr>'; 26 break; 27 } 28 $str = str_replace($match[0], $v, $str); 29}

変換対象の文字列を「 : 」で分割して処理をしていたのに、変換後の内容にも「 : 」を含めてしまい、意図しない結果になっていました。お騒がせしました。

投稿2019/12/12 11:53

ippya

総合スコア31

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問