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

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

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

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

正規表現

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

Q&A

解決済

2回答

1732閲覧

PHP_正規表現又はDOMを使用して適切な抽出方法

SugiuraY

総合スコア317

PHP

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

正規表現

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

0グッド

1クリップ

投稿2017/02/07 08:31

お世話になります。
現在、phpを使用しており正規表現またはDOMで以下のHTMLのようなデータから
一定の情報を正規表現又はDOMを使用することにより、抽出する事を試みております。
*正規表現により取得するデータは既に既にこちらのクライアント側にあるHTMLファイルであり、
取得先のサーバーへの負担等の問題は今回はご配慮頂かなくとも問題ございません。

【目的】
例えばですが、下記のHTMLをレンダリングした結果、以下のような構成になっております。
(A) aaaaa
(B) bbbbb,bbbbb
(C) ccccccc

これを例えば(A)について、以下のようなデータの抽出の方法を模索しています。

<p style="margin-left: 14px; text-align: justify; text-justify: inter-ideograph"> </p> <p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph"> <span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">(A)</span> </p> <p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph; text-indent: 14px"> <span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">aaaaa</span> </p>

つまり(A)のブロックについて、次の(B)のブロックの直前まで、タグを含めてブロック毎することが趣旨になります。

【状況】
1.ここで(A)(B)(C)の前後のタグは特に法則ないです。
例えば、(A)の前にある以下のタグも必ず他のタグでもそうであるわけではありません。

<p style="margin-left: 14px; text-align: justify; text-justify: inter-ideograph"> </p> <p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph"> <span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">

2.今回は抜粋として(A)(B)(C)のブロックをお示ししましたが、実際には(A)(C)や(A)(D)(E)といったパターンもあり
これらのパターンを含めてブロックを取得する方法を一般化しようとしております。

3.全てに共通することは(A)(B)....(Z)について、これらがどのようなものであるかは把握されております。
例えば、(北海道)札幌市 (兵庫県)神戸市のようにイメージして頂ければと思います。

【質問】
・上記の通りタグやタグの属性法則がないため、DOMをうまく利用することができないのですが、
このようなケースでDOMで目的にあるようなブロックを取得することができるのでしょうか?
nodeValue((A)とかの内容)は分かっているの、そこからアプローチができるかとも思ったのですが、
試行錯誤しても目的を達成できませんでした。
・正規表現でやる場合に様々なケースに対応する必要があるため、難しいとは思うのですが(A)をキーにして
そのブロックを取得するのは可能でしょうか?また、そもそもこのようなケースの場合、DOMや正規表現ではない
方法が推奨される場合には、なにかアイデアがあればご助言を頂ければ幸いです。

HTML

1<p style="margin-left: 14px; text-align: justify; text-justify: inter-ideograph"> </p> 2<p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph"> 3<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">(A)</span> 4</p> 5<p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph; text-indent: 14px"> 6<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">aaaaa</span> 7</p> 8<p style="text-align: justify; text-justify: inter-ideograph"> </p> 9<p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph"> 10<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">(B)</span> 11</p> 12<div style="margin-left: 24px"> 13<table style="table-layout: fixed; width: 624px" cellpadding="0" cellspacing="0"> 14<colgroup> 15<col style="width: 156px"/> 16<col style="width: 468px"/> 17</colgroup> 18<tbody> 19<tr> 20<td style="width: 155px; border-left: 1px solid transparent; border-right: 1px solid transparent"/> 21<td style="border-left: 1px solid transparent; border-right: 1px solid transparent"/> 22</tr> 23<tr style="min-height: 1.33333337306976px"> 24<td style="border-left: 1px solid #000000; border-top: 1px solid #000000; border-right: 1px solid #000000; border-bottom: 1px solid #000000; vertical-align: top"> 25<p style="margin-left: 24px; margin-right: 4px; text-align: justify; text-justify: inter-ideograph; text-indent: -18px"> 26<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">bbbbb</span> 27</p> 28</td> 29<td style="border-left: 1px solid #000000; border-top: 1px solid #000000; border-right: 1px solid #000000; border-bottom: 1px solid #000000; vertical-align: top"> 30<p style="margin-left: 24px; margin-right: 4px; text-align: justify; text-justify: inter-ideograph"> 31<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">bbbb</span> 32</p> 33<p style="margin-left: 24px; margin-right: 4px; text-align: justify; text-justify: inter-ideograph"> 34<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">bbbbbb</span> 35</p> 36</td> 37</tr> 38</tbody> 39</table> 40</div> 41<p style="text-align: justify; text-justify: inter-ideograph"> </p> 42<p style="margin-left: 36px; text-align: justify; text-justify: inter-ideograph"> 43<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">(C)</span> 44</p> 45<p style="margin-left: 60.6666679382324px; text-align: justify; text-justify: inter-ideograph"> 46<span style="font-family: &apos;MS Mincho&apos;; font-size: 12px">ccccccc</span> 47</p> 48

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

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

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

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

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

think49

2017/02/07 08:54 編集

何を起点として抽出条件とするのかが不明瞭です。id,class属性が割り当てられているわけでもないようですが、`(A)`, `(B)` は抽出条件として使えるユニークな文字なのでしょうか。 あるいは、「style属性値が今後変更されない」という前提の元、style属性値を抽出条件にするのでしょうか。
SugiuraY

2017/02/07 09:24

ご返信有難うございます。不明瞭な点お詫び申しあげます。>`(A)`, `(B)` は抽出条件として使えるユニークな文字なのでしょうか。 (回答)【状況】3.に記載のあるとおりユニークです。>あるいは、「style属性値が今後変更されない」という前提の元、style属性値を抽出条件にするのでしょうか。【状況】1.にあるとおり、ユニークではありません。ユニークなのはnodeValueとしての(A),(B)、、(Z)だけになります。またその範囲は既知であるということとなります。
guest

回答2

0

見た感じ
(classは省略)

html

1<p> </p> 2<p> 3 <span>(A~C)</span> 4</p>

で区切れそうなんだけどダメなの?

投稿2017/02/07 09:17

turbgraphics200

総合スコア4267

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

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

SugiuraY

2017/02/07 09:43

ご回答を頂き有難うございます。 量が膨大のため、割愛をしておりますが、pタグとspanタグの関係は保証されておりません。唯一保証されているのは、(X)の中身に入りうるものを知っている、またそのブロックの範囲は次の(Y)のブロックがくるまでという点になります。ただし、最初に来るブロックと最後のブロックは前か後ろしか他のブロックに囲まれていないことになります。
guest

0

ベストアンサー

前提の理解が間違っているかもしれませんが、「(北海道)札幌市」とかのイメージで考えると、以下のような形はいかがでしょうか。
(早く帰りたいのでソースがかなり雑ですが)

PHP

1<?php 2$dom = new DOMDocument('1.0', 'UTF-8'); 3#$dom->preserveWhiteSpace = false; 4#$dom->formatOutput = true; 5$dom->load("sample.html"); 6 7$xpath = new DOMXPath($dom); 8 9$result = $xpath->query("//p/span"); 10echo "<ul>"; 11foreach($result as $element) { 12 $node = $element->nodeValue; 13 if(preg_match('/((.*))/i', $node, $matches)) { 14 echo "</ul>".PHP_EOL; 15 echo "<p>$node</p>".PHP_EOL; 16 echo "<ul>".PHP_EOL; 17 } else { 18 echo "<li>$node</li>".PHP_EOL; 19 } 20} 21echo "</ul>".PHP_EOL;

この結果は

HTML

1<ul></ul> 2<p>(A)</p> 3<ul> 4<li>aaaaa</li> 5</ul> 6<p>(B)</p> 7<ul> 8<li>bbbbb</li> 9<li>bbbb</li> 10<li>bbbbbb</li> 11</ul> 12<p>(C)</p> 13<ul> 14<li>ccccccc</li> 15</ul>

となります。

Xpathで、<p>タグに囲まれた<span>タグを取得して、その中身を正規表現で取っています。
より正確にするためには、pタグのstyleやspanタグのstyle等を指定して

PHP

1$result = $xpath->query("//p[@style='margin-left: 36px; text-align: justify; text-justify: inter-ideograph']/span");

などするとうまい事取れると思います。
(例示ソースを見ると、なぜかstyleが要素ごとにぶれているので、うまい事する必要はありそうですが)

投稿2017/02/07 09:25

kunai

総合スコア5405

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問