質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.46%
div

HTMLの<div>タグです。<div>要素は特に意味を持っていません。ひとかたまりのコンテンツに使用されるか、(セマンティックとして)他の要素では記述できないコンテンツに使用されることが多いです。

PHP

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

1423閲覧

PHPの正規表現で、改行を含む全ての文字列をいれた抽出で、その中で最短一致を抽出したい。

gugupoo

総合スコア31

div

HTMLの<div>タグです。<div>要素は特に意味を持っていません。ひとかたまりのコンテンツに使用されるか、(セマンティックとして)他の要素では記述できないコンテンツに使用されることが多いです。

PHP

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2020/08/28 01:54

編集2020/08/28 02:07

表題の通りの質問をさせて頂きたいのですが、その表現が曖昧で具体的でないと思いますので、
実際に抽出したい例を以下に記載致します。

html

1<div style="width:500px" class="box"> 2<div class="title" style="background:blue" id="site1"><a href='http://test.com_1' target="_blank">テスト1</a></div></div> 3 4 5<div style="width:500px" class="box"> 6<div class="title" style="background:blue" id="site2"><a href='http://test.com_2' target="_blank">テスト2</a></div></div> 7 8 9<div style="width:500px" class="box"> 10<div class="title" style="background:blue" id="site3"><a href='http://test.com_3' target="_blank">テスト3</a></div></div> 11 12 13<div style="width:500px" class="box"> 14<div class="title" style="background:blue" id="site4"><a href='http://test.com_4' target="_blank">テスト4</a></div></div> 15 16 17<div style="width:500px" class="box"> 18<div class="title" style="background:blue" id="site5"><a href='http://test.com_5' target="_blank">テスト5</a></div></div>

このようなhtmlの中から、4つ目の群、 idで言うsite4 http://test.com_4の部分、

html

1<div style="width:500px" class="box"> 2<div class="title" style="background:blue" id="site4"><a href='http://test.com_4' target="_blank">テスト4</a></div></div>

を抽出したいのですが、うまく出来ずにいるので質問させて頂きます。

デリミタは#としてみました。

PHP

1$pattern = '#<div style="width:500px" class="box">(.*)http://test.com_4(.*)</div></div>#'; 2preg_match($pattern,$kijihtmltag,$match);

こちらでマッチはしませんでした。
$patternを以下に変えると

PHP

1$pattern = '#<div class="title"(.*)http://test.com_4(.*)</div></div>#';

html

1<div class="title" style="background:blue" id="site4"><a href='http://test.com_4' target="_blank">テスト4</a></div></div>

この部分は抽出に成功しました。

ここは抽出できるのに、<div style="width:500px"ここからは抽出できないのはなぜかと思い調べてみると、 .* これが改行は含まないという事を確認して、
[\s\S]* これだと改行を含んだ全ての文字となるとの事で、

PHP

1$pattern = '#<div class="title"([\s\S]*)http://test.com_4(.*)</div></div>#';

としてみた所、抽出結果は、

html

1<div style="width:500px" class="box">~~~~~~~~中略~~~ 2~~中略~ 3~~中略~ 4~~中略~ 5~~中略~ 6~~中略~~~~~中略~~~中略~~~中略~~~ テスト4</a></div></div>

上から下まで、4つの群を全て抽出してしまった次第です。
適当に思いつくがままに、
([\s\S]*) 

という部分を、 
([\s\S]*?) 
と変更してみても
4つの群を全て抽出してしまいます。

ので、大体表題のような具合の質問になりますが、

改行を含む文字列を間に挟み、
その前にいくつも同じ形式(例:ここでは <div style="width:500px" )があったとしても
そこの最短での(ここで言うと一番近いところ)の部分を抽出したい、となりますが、

正しい抽出のパターンを教えて頂きたいので宜しくお願い致します。

$patternには、 http://test.com_4を含み、その前半部分を正しく変化させる事で、うまくマッチさせる方法をお教え頂きたいです、宜しくお願い致します。

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

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

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

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

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

yambejp

2020/08/28 01:58

4つめの群のclassが抽出前と後でちがう
gugupoo

2020/08/28 02:08

すみませんでした。class="box" に修正しました。
guest

回答2

0

ベストアンサー

これは正規表現でやることではありません。
またグルーピングするなら同じclassを付加するとか
グループ自体をなにかでラップするとかしないと選びようがありません

投稿2020/08/28 02:00

yambejp

総合スコア115010

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

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

yambejp

2020/08/28 02:01

タグなど入れ子処理は正規表現の最も不得意とするものの1つです。 DOMDocumentなどで処理するのが妥当です
gugupoo

2020/08/28 02:12 編集

yambejp様 有難うございます。 ただ、記載させて頂いた通り、 <div class="title"  と、改行の後からなら問題なく抽出できるのですが、改行を挟むと、正しく抽出するのは難しくなる、という所でしょうか。。 自分も引き続いてマッチするパターンを探ってはみますが…。
yambejp

2020/08/28 02:20 編集

「4番目の」的な部分が抜きだしづらいです。 正規表現の場合入れ子なのか並列なのかが判断しづらいからです。 (複雑なやり方をすればできますが・・・) </div></div>がそのグループの終わりだという保証がありません
gugupoo

2020/08/28 02:22

なるほど、左様でございますか。有難うございます。 とりあえず自分も引き続き、色々なパターンを一応模索して続けてはみます。
yambejp

2020/08/28 02:30

とりあえず例示のものに限定していいならこれで抜けますが・・・ $pattern = '#<div style="width:500px" class="box">[\r\n]*(.*?)http://test.com_4(.*)</div></div>#';
gugupoo

2020/08/28 03:04

yambejp様 有難うございました! 限定というおっしゃる意味がよく分かりました。 暫定的というか、 class="box"のあたりの変化によっては抽出できない可能性があり、 本当の意味で色々応用の効く満足の行くものではないかもしれないが、という事だと思われますが、 ただこれで、少し今いくつか、test.com_3ですとか他も色々やってみて、 今はこの限定的なものを抽出する方法の正規表現では成功をして満足をえる結果ができました。 class="box"部分や、改行の個数その他によっては、 正規表現をまた作り直さなくはいけないという事だと予想致しますが、 今はこれで満足となりますので、他方法も勉強していきたいと思います。 有難うございました!
yambejp

2020/08/28 03:09

HTMLはどこで改行がはいるかなどゆるいので文字列として抜き出すのが結構 むづかしいんですよ。DOMで管理するのが妥当です。 PHPだけではなくJSなんかだと特にその傾向にあります
guest

0

デリミタは#としてみました。

と書かれている最初のパターン、"box4"となるべきところが、"box"になってます。

あとは、.が改行にもマッチするようにs修飾子を付けて、

PHP

1$pattern = '#<div style="width:500px" class="box4">(.*?)http://test.com_4(.*?)</div></div>#s';

投稿2020/08/28 02:30

otn

総合スコア84798

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

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

gugupoo

2020/08/28 02:39

otn様 有難うございます。 そして私の記載ミスで申しわけありませんが、修正済ではありますが、 class="box4" の部分、こちらはbox1もbox2も最初の表記部分は 全てboxと修正致しました。 その上で、 $pattern = '#<div style="width:500px" class="box">(.*?)http://test.com_4(.*?)</div></div>#s'; とさせて頂くと、今、また試させて頂きましたが、 このhttp://test.com_4 のかたまりのみでなく、 1つめから4つ目まで全て抽出してしまいました;; すみませんいかがすればよろしいでしょうか・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問