-2

テキストを分離するための正規表現の作成について助けが必要です。今、私はいくつかのテキストを持っています

text text text
text text text
<div> text text text </div>
<table class="table1">
<tr>
<td>
</td>
</tr>
</table>
text text text
text text text
text text text
<table class="table2">
<tr>
<td>
</td>
</tr>
</table>
text text text
text text text
text text text

テキストとテーブルを分離する正規表現を作成する必要があります。今、私は正規表現を持っています

preg_match_all( "/(.*)(<table(?s).*?\/table>)(.*)/si", $value[ 'TEXT' ], $matches );

そして、この表現は次のようなテキストに対してうまく機能します

text text text
text text text
<div> text text text </div>
<table class="table1">
<tr>
<td>
</td>
</tr>
</table>

それはに分離します

text text text
text text text
<div> text text text </div>

    <table class="table1">
    <tr>
    <td>
    </td>
    </tr>
    </table>

でもテキストに関しては

text text text
text text text
<div> text text text </div>
<table class="table1">
<tr>
<td>
</td>
</tr>
</table>
text text text
text text text
text text text
<table class="table2">
<tr>
<td>
</td>
</tr>
</table>
text text text
text text text
text text text

正規表現が機能しません。それは戻り配列です

[0] =>"text text text
    text text text
    <div> text text text </div>
    <table class="table1">
    <tr>
    <td>
    </td>
    </tr>
    </table>
    text text text
    text text text
    text text text",
[1]=>"<table class="table2">
    <tr>
    <td>
    </td>
    </tr>
    </table>",
[2]=>"text text text
    text text text
    text text text"

正しい正規表現を構築するには?

4

3 に答える 3

1

それはこのあたりのどこかにあるはずです:

$doc = new DOMDocument;
$doc->loadHTML('html string');

$tables = $doc->getElementsByTagName('table');
foreach($tables as $table){
    $parent = $table->parentNode;
    $parent->removeChild($table);
}

$doc->normalizeDocument();

$text = array();
$xpath = new DOMXPath($doc);
$textnodes = $xpath->evaluate('//text()');
foreach($textnodes as $textnode){
    $text[] = $textnode->wholeText;
}
print_r($text)

このコードは、html をロードし、テーブルを見つけて削除し、すべてのテキストノードを見つけて、その内容で配列を埋めます。PHP DOMの詳細を読んで、ニーズに合わせて微調整する必要があります。

于 2012-09-10T08:40:35.117 に答える
0

最善の解決策は次のコードです。

$test = preg_replace( "/<table(?s).*?\/table>/si", '<BREAKHERE>', $value[ 'TEXT' ] );

            $texts = explode( '<BREAKHERE>', $test );

            foreach ( $texts as $keyTEXT => $valueTEXT )
            {
                $TmpVal = str_replace( "\r", "", $valueTEXT );
                $TmpVal = str_replace( "\n", "", $TmpVal );
                $TmpVal = str_replace( "\r\n", "", $TmpVal );
                if ( trim( $TmpVal ) != '' )
                {
                    preg_match_all( "/\w/", $TmpVal, $mtchs );

                    if ( count( $mtchs[ 0 ] ) > 0 )
                    {
                        $value[ 'TEXT' ] = str_replace( $valueTEXT, ' <div class="panel-container">' . $valueTEXT . '</div>', $value[ 'TEXT' ] );
                    }
                }
            }
于 2012-09-10T12:14:57.657 に答える
0

(.*)正規表現の最初と最後にある を取り除きます。matches()そのような正規表現を「パディング」する必要があるのは、両端で一致を自動的に固定するJava のメソッドのようなものを使用している場合だけです。

ここで何が起こっているかというと、最初に最初にドキュメント全体を飲み込んでから、次の部分 (など) が 1 つのテーブル要素と一致(.*)するまで後退します。<table次に、2番目(.*)は残っているものをすべて消費します。これは、preg_match_all()テーブル要素を 1 つだけキャプチャする理由と、それが常に最後の要素である理由を説明しています。

を取り除くこともできます(?s)single-line実際には何も害はありませんが、モードをオンにするだけsで、最後の修飾子で既にそれを行っています. 空白文字 ( \s) に一致させるつもりだったのかもしれませんが、それでは一致できなくなり<table>ます (つまり、属性のないテーブル タグ)。\b代わりに (単語境界)を使用する必要があります。

preg_match_all( '~<table\b.*?/table>~si', $value[ 'TEXT' ], $matches );

ただし、このアプローチは非常に単純な HTML でのみ機能することに注意してください。完全に有効な HTML (入れ子になったテーブル タグが最も明白な例です) であっても、それを打ち負かすことができるものはたくさんあります。

于 2012-09-10T09:45:13.937 に答える