1

解析する次の html があります。

<h1 class="x">test</h1>
<p>some text <img src="x" /></p>

<h1 class="x1">test2</h1>
<p>some text </p>

<h1 class="2">test3</h1>
<p>some text <img src="x" /></p>

これを単一の正規表現で配列に解析できますか?

私は試した

preg_match_all('#(<h1[^>]*?>)(.*?)(</h1>)(.*)#ism',$html,$arr);

正規表現の最後の部分が貪欲であるため、エントリは 1 つしかありません。

preg_match_all('#(<h1[^>]*?>)(.*?)(</h1>)(.*?)#ism',$html,$arr);

<h1>式が貪欲ではないため、 の間の HTML については何もわかりません。

可能な限り多くのオカレンスを一致させながら、一致した後の部分を貪欲にするにはどうすればよいですか?

追加コメント:

  • 質問はかなり学術的です。私は pre_split を使用して問題を解決しましたが、他のさまざまな方法が機能しますが、欠点もあります (たとえば、DOM は制御できない無効な HTML では機能しない可能性があります)。しかし、それは私がもっと知りたいと思う繰り返しの問題です。
4

2 に答える 2

4

何らかの形のエンドメーカーが必要です。正規表現は、一致させたい部分まで推測できません。

(.*?)この場合、最後に の後の先読みアサーションが考えられます。

(?=<h1|</body>|\z)#ims
于 2011-03-02T21:59:50.357 に答える
1

正規表現がどのように不適切であるかについてのコメントは無視しますが、これは興味深い問題であるため、これにアプローチするには 2 つの方法があります: 貪欲と怠惰です。

パターンのそれぞれの部分は次のとおりです。

  • レイジー:.*?(?=<h1|\z)
  • 貪欲(?:[^<]+|<(?!h1))*

貪欲な修飾子と怠惰な修飾子の一般的なパフォーマンスに精通しているかもしれませんが、ここでの核心ははるかに単純です。

一致させようとしている文字列が完全に文字 で構成されている場合、<一致するすべての文字のアサーションを両方ともチェックする必要があるため、怠惰なパターンと貪欲なパターンはほぼ同じように実行されます。

ただし、HTML では、文字以外の文字がはるかに多い<ため、他の文字をチェックする必要のない貪欲なパターンは、桁違いに高速になる可能性があります。

怠惰なパターンの方が読みやすいことは認めますが、パフォーマンスが大幅に向上するだけの価値があると思いますx。いずれにせよ、パターンに修飾子を付けてコメントすることを強くお勧めします。

于 2011-03-02T22:06:35.797 に答える