正規表現に問題があります:
$var = preg_replace("/\[doxer_quote\]([^]]+)\[\/doxer_quote\]/", '<blockquote>$1</blockquote>', $var);
タグ内のコンテンツを表示させようとしていますが、blockquote
わかりません。また、複数の行にまたがる必要があります。誰か助けてくれませんか。
正規表現は、内部[doxer_quote]
に「タグ」を含まない文字列で正常に機能します。たとえば、次のようになります。
[doxer_quote]my
multiline
text[/doxer_quote]
ただし、ネストされたタグでは、単一行のコンテンツであっても失敗します。たとえば、次のようになります。
[doxer_quote]my [strong]formatted[/strong] text[/doxer_quote]
その理由は、]
この繰り返しの文字クラスによって文字まですべてを一致させているためです: [^]]+
、最初のネストされたタグが一致すると壊れます。
解決策: に置き換え[^]]+
、正規表現.+
に-modified を含めます。つまり:s
$var = preg_replace("/\[doxer_quote\](.+)\[\/doxer_quote\]/s", '<blockquote>$1</blockquote>', $var);
-修飾子 ( PCRE_DOTALLs
と呼ばれる) は、ドットを改行を含む任意の文字に一致させます。
マークアップ言語にネストされた[doxer_quote]
要素を含めることが許可されている場合、それは正規ではありません。正規表現は、通常の言語のみを処理するためにあります。
ネストされた要素を正規表現で照合するエレガントな方法はありません。次の状況を考えてみてください。
[doxer_quote]
[doxer_quote]
Lorem ipsum dolor sit amet
[/doxer_quote]
[/doxer_quote]
consetetur sadipscing elitr
[doxer_quote]
sed diam nonumy
[/doxer_quote]
単一の正規表現呼び出しで処理することはできません。
ただし、次のようにループで実行できます。
while(($var2 = preg_replace("/\[doxer_quote\]((?:(?!\[doxer_quote\]).)+?)\[\/doxer_quote\]/s", '<blockquote>$1</blockquote>', $var)) !== $var)
$var = $var2;
ステップバイステップの説明:
.
任意の文字に一致
(?!\[doxer_quote\]).
シーケンス「[doxer_quote]」の先頭以外の任意の文字に一致します。(?!)
は否定先読みと呼ばれます。
(?:(?!\[doxer_quote\]).)
上記は非キャプチャ サブパターンにグループ化されます。
(?:(?!\[doxer_quote\]).)+
1 回以上 繰り返されるサブパターンに一致します。
(?:(?!\[doxer_quote\]).)+?
- 反復量指定子の?
後は+
、量指定子を遅延させます (非貪欲とも呼ばれます)。
((?:(?!\[doxer_quote\]).)+?)
- 括弧はキャプチャ サブパターンを定義します。$1
置換式で参照されます。
ループでは、最も内側のタグがすべてのステップで置き換えられます。反復後に文字列が変更されなかった場合、ループは中断されます。
マークアップが常に適切にフォーマットされており (すべての開始タグが閉じられているなど)、マークアップ言語のタグに属性などが含まれていないことが確実な場合は、コンテンツを一致させずに、開始タグと終了タグを直接置き換えることを検討してください。
$var = str_replace(
array('[doxer_quote]', '[/doxer_quote]'),
array('<blockquote>', '</blockquote>'),
$var
);
この方法で、複数のタグ ( だけでなく[doxer_quote]
) を 1 つのステップで処理できます。
マークアップ言語の解析を検討してください。
https://stackoverflow.com/a/2101427/2277620を参照してください。multiline- 修飾子を使用しますが、貪欲な "+" のままにしておくと、最初のブロックの始まりから最後のブロックの終わりまでのテキストが取得されます。