【PHP】対になるタグを見つけて間の文字列を取得する方法

この記事について

環境PHP
目的htmlの対になるタグを見つけて間の文字列を取得する
結果mb_striposで開始タグと閉じタグの位置を比較しながら進め、対になる閉じタグを特定する

つまずきポイント要約

  • 同じ要素のタグが入れ子になっている場合、単純な正規表現では取得できない

htmlタグ間の文字列を取得するには正規表現を利用する

例:divタグ間の文字列を取得するサンプルコード

preg_replace('/^.+<div>(.+?)<\/div>.+$/u','$1',$string)

しかしこのやり方が通用するのは、限られた条件のときでしかない。
同じ要素のタグが入れ子になっている場合、不可能である。

divタグが入れ子になったHTML。これだとダメ

<body>
<div>
テスト文章1
  <div>
  テスト文章2
   <div>テスト文章3</div>
  </div>
</div>
</body>

何とか正規表現でできないものかと悩んだが難しそうなので、別の方法を用いた。

対になるタグというのは言い換えれば、二番目以降の開始タグと、そのひとつ前の閉じタグの位置を比較したとき、閉じタグが手前で、開始タグが奥にある状態の閉じタグである。

対のタグを見つけるサンプルコード

//二番目の開始タグと最初の閉じタグの位置を確認する
$start_pos = mb_stripos($content_html,"<div",6); //二番目の開始タグを見つけたいので適当に6文字目から検索
$end_pos = mb_stripos($content_html,"</div>");

echo "<br>開始位置: " . $start_pos;
echo "<br>終了位置: " . $end_pos;


$i = 1;

//閉じタグが開始タグの前に来るまで繰り返し
while ($start_pos < $end_pos) {

$start_pos++; //次のタグを探すために1増加
$end_pos++;

//前回の位置以降のタグを探す
$start_pos = mb_stripos($content_html,"<div",$start_pos);
$end_pos = mb_stripos($content_html,"</div>",$end_pos);

//念のため10回繰り返してだめなら抜ける
if ($i > 10) {

echo "10回超えたので終える";
break;
}

$i++;

} //while

//対になるタグまでの文字列を抜き出す
$content_html = mb_substr($content_html,0,$end_pos);

関連記事

タイトルとURLをコピーしました