1

多くのテキスト/画像を含むブログ エントリがあり、そのブログから抜粋したいと考えています。より具体的には、2番目の画像タグの後まですべてを一致させたい

以下はサンプルテキストです。

私は次のような否定的な先読みを試しました

/[\w\r\n;:',."&\s*<>=-_]+(?!<img)/i

しかし、先読みを「+」修飾子に適用する方法がわかりません。誰でも手がかりを得ることができました。本当に感謝しています。

*override*
I've been stuck in a room lately, and though it's hard to stay creative all the time,         sometimes you need that extra kick. Well for some us we have to throw pictures of true creative genius at ourselves to stimulate us.

So sit back and soak in some inspiration I've come across the past year.

&nbsp;

&nbsp;

&nbsp;

<figure>
    <a href="">
    <img class="aligncenter" src="http://funnypagenet.com/wp-content/uploads/2011/07/Talesandminimalism_12_www.funnypagenet.com_.jpg" alt="" width="574" height="838" />
    </a>
    <figcaption></figcaption>
</figure>

&nbsp;

&nbsp;

&nbsp;

&nbsp;
<h4 style="text-align: center;">
    <a href="http://funnypagenet.com/tales-and-minimalism/">source</a>
</h4>
Couldn't find who did this, but couldn't explain the movie any simpler

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

&nbsp;

<figure>
    <img class="aligncenter" src="http://brickhut.files.wordpress.com/2011/05/theempirestrikesback1.jpg" alt="" width="540" height="800" />
    <figcaption></figcaption>
</figure>

&nbsp;

&nbsp;

&nbsp;
4

3 に答える 3

3

単純な文字列の切断は、2 番目の画像には適していないことは明らかです。

...
<figure>
    <img class="aligncenter" src="http://brickhut.files.wordpress.com/2011/05/theempirestrikesback1.jpg" alt="" width="540" height="800" />
    <figcaption></figcaption>
</figure>

画像の後で切り取ると、閉じていない要素が残ります。

...
<figure>
    <img class="aligncenter" src="http://brickhut.files.wordpress.com/2011/05/theempirestrikesback1.jpg" alt="" width="540" height="800" />

これにより、ブラウザ内のページのレンダリングが破壊される可能性があります。preg_matchここで正規表現またはいくつかの文字列関数を使用する場合、それは役割を果たしません。

必要なのはDOMDocument、HTML を処理できるような DOM パーサーです。

問題のあなたのものに似たいくつかのサンプルHTMLコードを考えると:

$html = <<<HTML
dolor sit amet, consectetuer adipiscing elit. <img src="http://example.com/img-a.jpg"> Aenean commodo 
ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, 
nascetur ridiculus mus.

<figure>
    <img src="http://example.com/img-b.jpg">
    <figcaption>Figure Caption</figcaption>
</figure>

Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut.
HTML;

DOMDocumentこのクラスを使用して、HTML チャンクを<body>タグ内にロードできるようになりました。これは、操作用の HTML 本体全体であるためです。非標準の HTML タグ ( <figure>& ) を使用しているため、文字列を次<figcaption>のようにロードするときの警告を無効にする必要があります。libxml_use_internal_errors

$doc = new DOMDocument();
libxml_use_internal_errors(1);
$doc->loadHTML(sprintf('<body>%s</body>', $html));

これは DOM パーサーの基本的なセットアップです。HTML はパーサー内に配置されます。次に興味深い部分です。文書の 2 番目の画像までの抜粋を作成します。つまり、その要素以降はすべて削除する必要があります。うまくいかないことがわかっている文字列を切り取るのと同じくらい簡単に聞こえますが、今回は DOM パーサーがすべての作業を行ってくれます。

すべてのノード ( <tag>、テキスト、<!-- comments -->...) を取得して削除するだけです。<img>の 2 番目のタグの後のすべてのノード(次のドキュメント順)。そのようなことはXPathで表現できます:

/descendant::img[position()=2]/following::node()

PHP の DOM パーサーには XPath が付属しているので、実行してみましょう。

$xp = new DOMXPath($doc);
$delete = $xp->query('/descendant::img[position()=2]/following::node()');
foreach ($delete as $node)
{
    $node->parentNode->removeChild($node);
}

残っている唯一のことは、残っている抜粋を取得することです (出力例)。私たちが知っているように、それはすべて<body>タグの中にあります:

foreach ($doc->getElementsByTagName('body')->item(0)->childNodes as $child)
{
    echo $doc->saveHTML($child);
}

これにより、次のことが得られます。

dolor sit amet, consectetuer adipiscing elit. <img src="http://example.com/img-a.jpg"> Aenean commodo 
ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, 
nascetur ridiculus mus.

<figure><img src="http://example.com/img-b.jpg"></figure>

この例が示すように、<figure>タグは適切に閉じられています。

同様のシナリオは、特定のテキスト長または単語数の後に抜粋を作成することです: Wordwrap / HTML 文字列内のテキストをカット

于 2012-02-24T20:21:38.573 に答える
1

まあ、それは正規表現ではありませんが、うまくいくはずです:

$post = str_ireplace('<img', '!!!<img', $post);
list($p1, $p2) = explode('!!!', $post);
$keep = $p1 . $p2;

画像タグ(!!!)の前に分割マーカーを配置し、それらを分割して最初の2つのチャンクを保持します。これは、2番目の画像タグまでのすべてである必要があります。正規表現は必要ありません。

編集:これは抜粋用であるため、結果を実行することをお勧めしますstrip_tags()。そうしないと、閉じられないHTMLタグが開かれる可能性があります。

于 2012-02-24T19:40:23.537 に答える
0

本当に正規表現ベースのソリューションが必要な場合は、次のとおりです。

// assuming $str is your full HTML text
if ( preg_match_all('~^(.*?<img\s.*?<img\s[^>]*>)~si', $str, $m) )
    print_r ( $m[1] );
于 2012-02-24T19:41:22.210 に答える