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

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

ただいまの
回答率

90.51%

  • PHP

    24054questions

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

  • 正規表現

    924questions

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

[正規表現]英語の文章だけを排除したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 735

kalon

score 90

皆様、平素よりお世話になっております。

「<div class="en_text">と<br />に囲われた英語の文章」だけを除外して表示したいのですが、以下のように自分なりのコードを書いてみたのですが、どうしても実現できません。

ini_set('display_errors',1);
header("Content-Type: text/html; charset=UTF-8");//文字化け防止


require_once('phpQuery.php'); //phpQueryというモジュールを使う

// HTMLデータを取得する
$html = file_get_contents('http://www.meigensyu.com/quotations/index/page1.html'); //ターゲットのURL

// HTMLをオブジェクトとして扱う
$doc = phpQuery::newDocument($html);
$messages= $doc['div.text']; //これだけでトリミングしたい要素が<html><header><body>付きで代入される

preg_match_all('|<div class="text">(.*)(</div>)|', $messages, $match); //$matchは<div>だけのきれいな配列になる。

/*$matchの「$match[0]にはHTML要素付き」、「$match[1]には平文」が入る。
平文の文章を抽出したい場合は$match[1][0]からのスタートになる*/
$singulerExpression = '<div class="text">'; //名言の入っている要素を指定
$singulerExpression_noEng ='|<div class="text">(.*)(<br />)|';

for($i=0;$i<count($match[1]);$i++){
    if(!preg_match($singulerExpression, $match[1][$i])){
        if(!preg_match($singulerExpression_noEng,$match[1][$i]))
            echo $match[1][$i].'<br/>';
    }
}


出力部分を以下のようにしても同じ出力結果でした。

for($i=0;$i<count($match[1]);$i++){
       echo preg_replace('|<div class="en_text">.*<br />|', '', $match[1][$i]).'<br />';
}

上記の出力結果

人間はひとくきの葦にすぎない。自然の中で最も弱いものである。だが、それは考える葦である。<div class="en_text">Human being is a reed of one stalk. It is the weakest existence naturally. However , it is a thinking reed .<br/>その日その日が一年中の最善の日である。<br/>チャンスは貯蓄できない。<br/>希望さえあればどんな所にでも たどりつけると決心している。<br/>死者にたいする最高の手向けは、悲しみではなく感謝だ。<br/>人生は道路のようなものだ。 一番の近道は、たいてい一番悪い道だ。<br/>世の中は、君の理解する以上に栄光に満ちている。<br/>人付き合いがうまいというのは、人を許せるということだ。<br/>生きるとは呼吸することではない。行動することだ。<br/>人生は学校である。 そこでは幸福より不幸の方が良い教師である。<br/>若い女は美しい。しかし、老いた女はもっと美しい。<br/>今日という日は、残りの人生の最初の一日。<br/>卵を割らなければ、オムレツは作れない。<div class="en_text">You can't make omelet without breaking eggs.<br/>至上の処世術は、 妥協することなく適応することである。<br/>人間、志を立てるのに遅すぎるということはない。<br/>太陽が輝くかぎり、希望もまた輝く。<br/>行動は必ずしも幸福をもたらさないかも知れないが、 行動のない所に、幸福は、生まれない。<br/>成し遂げんとした志をただ一回の敗北によって捨ててはいけない。<br/>

私の正規表現の書き方か、ロジックに間違えがあると思います。どうかアドバイスやご指摘のほどをお願いいたします。

以上です。よろしくお願いします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2016/09/20 04:17

    過去の質問について、「解決済」になっていないものがいくつか見受けられます。解決したものは「ベストアンサー」を選び、自力で解決した場合はその方法を解答欄に書き、もし万が一解決していないのであれば質問を編集するなどしてみてください。

    キャンセル

  • kalon

    2016/09/20 04:22

    ご指摘ありがとうございます。ご指摘の通り解決済みになっていない質問を解決済みにすることを失念しておりました。
    しかしながら、それら回答頂いた方法を今回のコードにも応用してみたのですが、自力で解決に至らなかったので今回このように質問させて頂きました。

    キャンセル

回答 2

checkベストアンサー

+4

DomDocumentとXPathを使って抽出してみました。
コメントを書いてあるので、参考にしてください。

<?php
ini_set('display_errors',1);

// HTMLデータを取得する
$html = file_get_contents('http://www.meigensyu.com/quotations/index/page1.html'); //ターゲットのURL

$dom = new DomDocument; // DomDocumentオブジェクトを作る
@$dom->loadHTML($html); // ターゲットのHTMLをDomDocumentに読み込ませる
$xpath = new DOMXPath($dom); // XPathオブジェクトを作る
$divs = $xpath->query('//div[@class="text"]'); // classがtextの<div>を探す
foreach($divs as $div) { // 見つかった<div>が配列になっているのでループで回す
    $en_divs = $xpath->query('div[@class="en_text"]', $div); // そのdivからclassがen_textの<div>を探す
    if($en_divs->length) { // divがあったら
        $div->removeChild($en_divs->item(0)); // en_textのdivを消す
    }
    echo $div->nodeValue ."\n"; // <div>内の値をechoで出力する
}

DomDocumentを使うと、HTMLを構造解析して、XPathでほしい情報を抽出できます。詳しくは、ここを読んで下さい。多くの場合、正規表現より正確かつ簡単に抽出できます。
phpQueryは、内部的にはDomDocumentとXPathを使ったスクレイピングライブラリですが、DomDocumentに比べて情報も少ないので、まずはPHP標準機能であるDomDocumentを素直に使うことをおすすめします。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/20 12:58

    素晴らしいアドバイスをありがとうございました。しかしながら、ご教授頂いたコードですと英語の文章だけが抽出されてしまい、私の実現したい「英語の文章だけの排除」とは違います。

    今理解できている限りで頂いたコードを応用してみたのですが、やはり英語の文章の排除が実現できませんでした。

    ```php
    <?php
    ini_set('display_errors',1);

    // HTMLデータを取得する
    $html = file_get_contents('http://www.meigensyu.com/quotations/index/page1.html&#039;); //ターゲットのURL

    $dom = new DomDocument; // DomDocumentオブジェクトを作る
    @$dom->loadHTML($html); // ターゲットのHTMLをDomDocumentに読み込ませる
    $xpath = new DOMXPath($dom); // XPathオブジェクトを作る
    $divs = $xpath->query('//div[@class="text"]'); // classがen_textの<div>を探す
    foreach($divs as $div) { // 見つかった<div>が配列になっているのでループで回す
    echo $div->nodeValue ."<br />"; // <div>内の値をechoで出力する
    }
    ```

    どうしたら.textだけを抽出して.en_textを除外できるのでしょうか?

    以上質問です。よろしくお願いします。

    キャンセル

  • 2016/09/20 13:51

    ごめんなさい!! マジボケしてました...
    直してみたので、試してみてください

    キャンセル

  • 2016/09/20 21:41

    コードの修正ありがとうございました。

    ですが、foreach文が"}"で終わっていなかったことを恐れながらご指摘させて頂きます。コードとして正しいのは以下のようです。

    ```php
    <?php
    ini_set('display_errors',1);

    // HTMLデータを取得する
    $html = file_get_contents('http://www.meigensyu.com/quotations/index/page1.html&#039;); //ターゲットのURL

    $dom = new DomDocument; // DomDocumentオブジェクトを作る
    @$dom->loadHTML($html); // ターゲットのHTMLをDomDocumentに読み込ませる
    $xpath = new DOMXPath($dom); // XPathオブジェクトを作る
    $divs = $xpath->query('//div[@class="text"]'); // classがtextの<div>を探す
    foreach($divs as $div) { // 見つかった<div>が配列になっているのでループで回す
    $en_divs = $xpath->query('div[@class="en_text"]', $div); // そのdivからclassがen_textの<div>を探す
    if($en_divs->length) { // divがあったら
    $div->removeChild($en_divs[0]); // en_textのdivを消す
    }
    echo $div->nodeValue ."\n"; // <div>内の値をechoで出力する
    }
    ```

    そしてこちら頂いたコードを上記のように修正して、実行すると以下のエラーを吐きます

    Fatal error: Cannot use object of type DOMNodeList as array in /myphp.php on line 14

    もう少しどのようなロジックで英語を除去しているのか読み込ませて頂き自分で解決できるように努力してみますが、引き続きご指導のほどよろしくお願いします。

    キャンセル

  • 2016/09/20 22:03 編集

    すみません... 最後の}が抜けてましたね。
    自分の環境ではこれで動くのですが、なんででしょうね...phpのバージョンでしょうか。
    ちなみにmyphp.phpの14行って以下ですよね?
    $div->removeChild($en_divs[0]); // en_textのdivを消す

    回答のPHPを直して見たので、もう一度やってみてください

    キャンセル

  • 2016/09/21 11:48

    ありがとうございました。頂いたコードで動きました。懇切丁寧なアドバイスの上に、コードまで書いてくださってありがとうございました。

    キャンセル

  • 2016/09/21 11:58

    うまく行ってホッとしてます。DomDocumentと正規表現をうまく使い分けながらスクレイピングするのがいいと思います。

    キャンセル

0

英語だけの文書ってstrlenとmb_strlenが一緒だって判断していいなら例えばこう

$str=<<<eof
<div class="en_text">hoge hoge hoge<br />hoge hoge</div>
<div class="en_text">hoge ほげ hoge<br />hoge hoge</div>
<div class="en_text">ほげほげ<br />hoge hoge</div>
<div class="jp_text">hoge hoge hoge<br />hoge hoge</div>
eof;
$pattern="|(?<=<div class=\"en_text\">).+(?=<br />)|";
$replacement=function($a){return strlen($a[0])==mb_strlen($a[0])?"":$a[0];};
$str=preg_replace_callback($pattern,$replacement,$str);
print nl2br(htmlspecialchars($str));

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • PHP

    24054questions

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

  • 正規表現

    924questions

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