0

この質問は以前によく聞かれたようですが、非常に長く、「<」や「{」などの特殊文字を含むデータの有効な解決策が見つかりませんでした。

サーバー上のPHPに巨大なXMLデータを送信しています。これは次のようになります。

<root><id>1</id><text>Here is a very long text with

line breaks, white-spaces and many very unsual charchaters, e.g. < % & }

the text can be more then 5000 characters long

</text></root>

サーバー側では、テキストタグ間の「生データ」を取得しようとしています。「テキストタグ」内の生データには、空白、改行、奇妙な文字など、イメージできるものなら何でも含めることができます。私が提出するのは、ソース コードとテキストで、CKEditor とコード シンタックスハイライターによってフォーマットされています。

私はこれを読んで、基本的に誰もが「XMLパーサーを使用する」と言います.domDocumentはRegExを使用しないように.

まず、たとえばいくつかの RegEx ステートメントを試しました。これは私が試した唯一のものではありません。データに角かっこが含まれていて、データが長すぎる場合、失敗します。

//#<text[^>]*>[\s\S]*?</text>#
$regex = "#<".$element_name."[^>]*>[\s\S]*?</".$element_name.">#";

$found = preg_match($regex, $xml, $matches);

if ($found != false) 
{
    $result = $matches[0];
    return $result;
}

次に、これを試してみました。これは、タグ内のデータがあまり奇妙でない場合に機能します。パーサーは角かっこ「<」が好きではなく、xml が有効ではないと考えています。

 function getTextBetweenTags($tag, $html, $strict=0)
{
    /*** a new dom object ***/
    $dom = new domDocument;

    /*** load the html into the object ***/
    if($strict==0)
    {
        $dom->loadXML($html);
    }
    else
    {
        $dom->loadHTML($html);
    }

    /*** discard white space ***/
    $dom->preserveWhiteSpace = false;

    /*** the tag by its tag name ***/
    $content = $dom->getElementsByTagname($tag);

    /*** the array to return ***/
    //$out = array();
    foreach ($content as $item)
    {
        /*** add node value to the out array ***/
        //$out[] = $item->nodeValue;
        /*** return only the first found element value ***/
        return $item->nodeValue;
    }
    /*** return empty string if nothing found ***/
    return "";
}

だから私の質問は:

私が正確に知っている場合、データ内に開始と終了の「テキスト」タグが1つしかない場合、PHPで生データを読み取る最良の方法は何ですか?

誰かが私に動作する正規表現またはコードスニペットをくれたら、それは素晴らしいことです.

私の中程度の英語で申し訳ありません。

===回答への回答===回答への回答===回答への回答===

わかりました、BogdanM と Steven からの両方の回答は機能しますが、私のお気に入りの回答は BogdanM からのものです。

私がしたこと。これを機能させるには:

  1. クライアント サイトで独自の XML を作成し、CDATA を使用してパーサーにデータの開始位置と終了位置を伝えます。
  2. サーバー側では、SimpleXML を使用してデータを解析します。CDATA を使用すると、解析に問題はなくなります。データがどんなに「変」でも構いません。
  3. HTTP-GET でビッグ データを送信する際によくある「ルーキー エラー」を排除しました。私は今、HTTP-POSTを使用して制限を設けていません

助けてくれてありがとう。

4

2 に答える 2

2

XMLも生成していますか?その場合は、テキスト データを CDATA の間に配置する必要があります。次に、xml を simplexml または選択したパーサーでロードし、テキスト タグの内容を取得します。UTF-8 文字や、XML でまったく許可されていない文字が含まれていないことを確認してください: http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char

そうでなければ、これを行うことができます:

preg_match('#<text>(.+?)</text>#is', $xml, $matches);
echo $matches[1]; // your data between <text> and </text>
于 2013-09-19T22:17:04.853 に答える
2

まず、元の正規表現パターンは問題なく、正常に動作するはずです。

#<".$item_name."[^>]*>([\s\S]*?)</".$item_name.">#

ただし、読みやすく/機能的にするために変更することもできます...

可能性

正規表現 1

#<text>(.*)</text>#is

textタグ間のすべてをキャプチャするだけです。修飾子iを使用して許可TEXTし、textタグを付け、改行s.一致させます。

正規表現 2

#<text.*?>(.*)</text>#is

元の正規表現は、開始textタグで余分な文字を受け取ることを期待していることを意味します。.*?開始タグ内の により、これが可能になります。?最初の で停止し>ます。

正規表現 3

#<(text).*?>(.*)</\1>#is

開始タグ名と終了タグ名が同じ (つまり) であるため、開始タグを括弧で囲んでキャプチャ グループにし、最初のキャプチャ グループtextであるため、終了タグで単純に参照できます。\1

つまり、スペルを間違える可能性が 1 つ少なくなります。

正規表現 4

#<('.$item_name.').*?>(.*)</\1>#is

よりダイナミックにします。単語textを変数に置き換えることができます(元のとおり)。これをキャプチャ グループと組み合わせて、Regex 3のように参照すると、変数を 1 回挿入するだけで、よりクリーンで読みやすいコードになります。

比較 v オリジナル

#<('.$item_name.').*?>(.*)</\1>#is
#<".$item_name."[^>]*>([\s\S]*?)</".$item_name.">#

実施例

上記の正規表現 4を使用する

$string = "
<root><id>1</id><text>Here is a very long text with

line breaks, white-spaces and many very unsual charchaters, e.g. < % & }

the text can be more then 5000 characters long 

</text></root>";

preg_match('#<('.$item_name.').*?>(.*)</\1>#is', $string, $matches);
var_dump($matches);

/**
Output:

array(3) {
  [0]=>
  string(167) "<text>Here is a very long text with

line breaks, white-spaces and many very unsual charchaters, e.g. < % & }

the text can be more then 5000 characters long 

</text>"
  [1]=>
  string(4) "text"
  [2]=>
  string(154) "Here is a very long text with

line breaks, white-spaces and many very unsual charchaters, e.g. < % & }

the text can be more then 5000 characters long 

"
}

*/

注:上記の実際の例を...動作させることができない場合は、おそらく(質問を編集するか、リンクすることによって)動作しない例を提供できますか?

于 2013-09-19T22:45:13.100 に答える