15

複数の行にまたがる可能性のある文字列を一致させようとしています。特定の文字列で開始および終了します。

{a}some string
can be multiple lines
{/a}

{a}{/a}の間のすべてを正規表現で取得できますか? のようです。新しい行と一致しませんが、次のことを試してみましたが、うまくいきませんでした:

$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/', 'X', $template, -1, $count );
echo $count; // prints 0

一致します。または \n 単独でいるが、一緒ではない場合!

4

3 に答える 3

33

s修飾子を使用します:

$template = preg_replace( $'/\{a\}([.\n]+)\{\/a\}/s', 'X', $template, -1, $count );
//                                                ^
echo $count;
于 2009-03-29T23:44:27.873 に答える
7

ドットが改行に一致しないだけでなく、もっと多くの問題があると思いますが、フォーマットの推奨事項から始めましょう。スラッシュ (「/」) だけでなく、ほぼすべての句読点を正規表現の区切り文字として使用できます。別の文字を使用する場合、正規表現内でスラッシュをエスケープする必要はありません。'%' が PHPers の間で人気があることは理解しています。それはあなたのパターン引数になります:

'%\{a\}([.\n]+)\{/a\}%'

正規表現が意図したとおりに機能しなかった理由は、ドットが文字クラス (角かっこ) 内に表示されるとその特別な意味を失うため[.\n]です。つまり、ドットまたは改行に一致するだけです。あなたが探していたのは でしたが(?:.|\n)、改行だけでなく改行も一​​致させることをお勧めします。

'%\{a\}((?:.|[\r\n])+)\{/a\}%'

これは、"改行" という単語が、Unix スタイルの "\n"、Windows スタイルの "\r\n"、または古い Mac スタイルの "\r" を参照できるためです。任意の Web ページには、これらのスタイルのいずれか、または 2 つ以上のスタイルの混合が含まれる場合があります。"\n" と "\r\n" の混合は非常に一般的です。しかし、/s モード (単一行モードまたは DOTALL モードとも呼ばれます) を使用すると、それについて心配する必要はありません。

'%\{a\}(.+)\{/a\}%s'

ただし、元の正規表現には別の問題があり、この正規表現にはまだ存在してい+ます。貪欲です。つまり{a}...{/a}、テキストに複数のシーケンスがある場合、正規表現が初めて適用されたときに、最初{a}から最後の{/a}. これを修正する最も簡単な方法は、+疑問符を追加して貪欲でない (別名、「怠け者」または「消極的」) ことです。

'%\{a\}(.+?)\{/a\}%s'

最後に、パターン引数の開始引用符の前にある「$」をどうすればよいかわかりません。私は PHP を使用していませんが、構文エラーのように見えます。誰かが私にこの件について教えてくれたら、ありがたいです。

于 2009-03-30T06:42:31.537 に答える
3

http://www.regular-expressions.info/dot.htmlから:

「ドットは、その文字が何であるかを気にせずに、単一の文字に一致します。唯一の例外は改行文字です。」

式の末尾に /s フラグを追加する必要があります。

于 2009-03-29T23:48:41.203 に答える