2

私は現在、bbcode 解析エンジンを作成していますが、自分では理解できない状況に遭遇しました。

問題は、私がこの問題とまったく同じような問題に遭遇したことです: Windows 上の Apache / PHP が正規表現でクラッシュする

つまり、以下の例のようなものを作成すると、再帰カウントが 690 (PCRE のメモリ制限は 1MB) に達するため、Apache がクラッシュします。

$txt = '[b]'.str_repeat('a', 338).'[/b]';  // if I change repeat count to lower value it's ok
$regex = '#\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))](?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)\[/(?P=tag)]#mi';

echo preg_replace_callback($regex, function($matches) { return $matches['content']; }, $txt);

*したがって、正規表現でandの必要性を何らかの形で最小限に抑える必要がありますが、+それは私がアイデアを持っていない場所なので、何か提案できるかもしれません.

(ネストされたタグを処理できる) bbcode を解析するための他のアプローチを歓迎します。しかし、私はすでに構築されたクラスなどを使用したくありません。何でも自分でやるのが好き!

PECL と Pear HTML_BBCodeParser も調べました。しかし、アプリケーションを拡張機能に依存させたくありません。おそらく、その拡張子をチェックするスクリプトを実行し、存在しない場合は、ここで実行しようとしている BBCode パーサーを使用する可能性があります。

私の説明が暗い場合は申し訳ありません。私は英語が得意ではありません^^

編集。したがって、正規表現は次のように説明しました。

\[(?P<attributes>(?P<tag>[a-z0-9_]*?)(?:=.*?|\s.*?|))]

これは私の開始タグです。名前付きグループを使用しました。「タグ」でタグを識別し、「属性」でタグの属性を識別します。タグも属性と考えてください。では、ここで何が起こっているのでしょうか? タグを一致させようとします。タグが一致する場合は、タグ クロージャに到達するまで、=記号の後のものまたは (スペーサー) の後のものと一致させようとします。\s]

(?P<content>(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)

ここで、コンテンツを一致させようとしています。これはトリッキーな部分です。[ ではない文字を探しています。見つかった場合は、それが終了タグまたは再帰でないかどうかを確認し、正規表現エンジンにそうするように指示します....

\[/(?P=tag)]

...終了タグが見つかりました。

4

2 に答える 2

3

正規表現、特にゼロ幅アサーション (ルックアラウンド) により、正規表現エンジンが壊滅的にバックトラックします。話の教訓: Regex can'tは、正規ではない言語の解析に使用すべきではありません。ネストされた構造がある場合、それは通常の言語ではありません。

実際、私はBBCodeがだと思っています。BBCode は、HTML を適切な方法でフィルタリングしたくない怠惰なプログラマーによって発明されたマークアップ言語です。その結果、実装が難しい緩い「標準」ができてしまいました。HTML を正しい方法でフィルタリングします。

http://htmlpurifier.org/

于 2010-08-31T21:35:05.643 に答える
2

私はBBCodeParserを提案するつもりでした...

PECL と Pear HTML_BBCodeParser も調べました。しかし、アプリケーションを拡張機能に依存させたくない

それはとても奇妙だと思います。なぜ車輪を再発明するのですか?優れたソフトウェア エンジニアリングの原則の 1 つは DRY (Don't Repeat Yourself) です。すでに解決済みの問題を解決しようとしています。

何でも自分でやるのが好き!

それ自体は悪くありませんが、実証済みの真の解決策を使用した方がよい場合もあります。あなた自身のものよりもよくテストされ、より堅牢なものです(あなたが見つけているように)。そうすれば、すでに解決済みの問題を解決するのではなく、実際に解決したい問題に時間を費やすことができます。車輪の再発明の罠にはまらないでください。:)

あなたへの私の提案 (および解決策) は、BBCode パーサーを使用することです。

編集

もう 1 つのことは、HTML のようなものを解析していることです。そのような性質のものは、正規表現で解析するのは簡単ではありません。

于 2010-08-31T21:34:11.247 に答える