質問
いを取り出そうとすると、特定のタグとそのコンテンツのxhtml文書でのマッチングを誤った終了タグです。
以下の内容:
<cache_namespace name="content">
<content_block id="15">
some content here
<cache_namespace name="user">
<content_block id="welcome">
Welcome Apikot!
</content_block>
</cache_namespace>
</content_block>
</cache_namespace>
のcontent_block終了タグid="welcome"を実際に取得し、合わせて、終了タグの開content_blockタグです。
の正規表現を使用しています:
/<content_block id="(.*)">([\w\W]*?)<\/content_block>/i
任意のポインタとしてどんな?
解決
...と答えはいつも同じです: HTML +正規表現はを行うことはできません。ごめんなさい。あなたの特定のフレームワークのためのHTML構文解析ライブラリを使用してください。あなたの文書が唯一の有効なXHTMLを含むことが保証されている場合、コメントのジッタによって提案されたり、XPathのアプローチを取るます。
他のヒント
これは役立つかもしれません 私は http://www.regular-expressions.info/examples.html の上のチュートリアルを見つけました これは与えられたテキストで繰り返し文字列のペアをキャプチャ言及しています。 提案は使用することですか?後に。*それは
テキスト内のペアの文字列を終了する最初に出現した後に停止にするためにこの正規表現の既知の問題です - あなたはペアを一致させることはできません。マッチングは、それが最初に一致している最後に見つけた1、または非貪欲に、一致する、のいずれか貪欲です。あなたは開閉ブラケットをカウントするために正規表現を説得することはできません。
私はDOMにロードし、それを使用することをお勧めします。あなたがHTMLパーサーを実装しようとしている場合、私はあなたのレクサーの出力を解析するために、その後、左右のパーサを、それをlexのために正規表現を使用することをお勧めします。
感謝 @Jan Żankowski や @池上, その答えにしてくれたinpiration
を使用させてもらいPHPを発揮するコード
<?php
$xml = <<<EOT
<cache_namespace name="content">
<content_block id="15">
some content here
<cache_namespace name="user">
<content_block id="welcome">
Welcome Apikot!
</content_block>
</cache_namespace>
</content_block>
</cache_namespace>
EOT;
preg_match('/<cache_namespace[^>]+>((?:(?!(<\/?div>)).)*)<\/cache_namespace>/s', $xml, $matches);
print_r($matches);
regex注
s
オプション:a.
パターンに一致すべての文字、改行- のビジネスモデルでビジネスをする
(?:(?!STRING).)*
は文字列として[^CHAR]*
は文字
結果
Array
(
[0] => <cache_namespace name="content">
<content_block id="15">
some content here
<cache_namespace name="user">
<content_block id="welcome">
Welcome Apikot!
</content_block>
</cache_namespace>
</content_block>
</cache_namespace>
[1] =>
<content_block id="15">
some content here
<cache_namespace name="user">
<content_block id="welcome">
Welcome Apikot!
</content_block>
</cache_namespace>
</content_block>
)
構文解析XHTMLはXMLではないです。って有効または整形のコードです。
#!/usr/bin/perl
use strict;
use warnings;
use v5.10;
my $xml = <<"EOF";
<cache_namespace name="content">
<content_block id="15">
some content here
<cache_namespace name="user">
<content_block id="welcome">
Welcome Apikot!
</content_block>
</cache_namespace>
</content_block>
</cache_namespace>
EOF
while ($xml =~ m!
<(content_block)\sid="welcome"> # Start tag definition.
(\s* # It may consists of
(?: <\!--.*?--> # - comment
| [^<]* # - text
| <[^>]+/> # - another closed tag
| <\s*(\w+)[^>]*> # - another tag with some content
(?2)+ # (recursive definition of possible tag content)
</\3>
)
)*
</\1>
!sxgc) {
print "==> $&\n\n";
}
を変更してください開始タグの定義のための別のコンテンツなど <\s*(\w+)[^>]*+>
).とにかく良い開始。
場合は使用しないで繰返し(線 (?2)+
まっ などの事例.このコードに対応した見てください こちらの 前)または容易に適応す。