PHPでさまざまなNewlineスタイルを最も賢い方法で置き換える方法は?
質問
異なる新しいラインスタイルを持つかもしれないテキストがあります。すべてのnewlines ' r n'、 ' n'、 ' r'を同じ新しいライン(この場合 r n)に置き換えたいです。
これを行うための最速の方法は何ですか?私の現在の解決策はこんなに吸うように見えます:
$sNicetext = str_replace("\r\n",'%%%%somthing%%%%', $sNicetext);
$sNicetext = str_replace(array("\r","\n"),array("\r\n","\r\n"), $sNicetext);
$sNicetext = str_replace('%%%%somthing%%%%',"\r\n", $sNicetext);
問題は、 r nが r n r nに複製されるため、1つの交換でこれを行うことができないことです。
ご協力ありがとうございました!
解決
$string = preg_replace('~\R~u', "\r\n", $string);
すべてのUnicode NewLinesを交換したくないが、CRLFスタイルのものだけを交換したくない場合は、以下を使用してください。
$string = preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $string);
\R
これらのニューラインに一致し、 u
入力文字列をUTF-8として扱う修飾子です。
から PCREドキュメント:
何
\R
マッチデフォルトでは、パターンのシーケンス rは、線の終了シーケンスとして選択されたものをすべてUnicode Newlineシーケンスと一致させます。指定した場合
--enable-bsr-anycrlf
デフォルトは、 rがCR、LF、またはCRLFのみに一致するように変更されます。 PCREが構築されたときに選択されるものはすべて、ライブラリ機能が呼び出されたときにオーバーライドできます。
と
Newlineシーケンス
キャラクタークラスの外で、デフォルトでは、エスケープシーケンス rは任意のUnicode Newlineシーケンスと一致します。非UTF-8モードでは、 rは次のものと同等です。
(?>\r\n|\n|\x0b|\f|\r|\x85)
これは「原子グループ」の例であり、その詳細を以下に示します。この特定のグループは、2文字のシーケンスCRに続いてLF、または単一文字LF(LineFeed、U+000A)、VT(Vertical Tab、U+000B)、FF(FormFeed、U+000C)、CRのいずれかと一致します。 (キャリッジリターン、u+000d)、またはnel(次の行、u+0085)。 2文字のシーケンスは、分割できない単一のユニットとして扱われます。
UTF-8モードでは、コードポイントが255を超える2つの追加文字が追加されています:LS(Line Separator、U+2028)およびPS(段落セパレーター、U+2029)。これらの文字が認識されるには、Unicode文字プロパティサポートは必要ありません。
コンパイル時またはパターンが一致したときにオプションPCRE_BSR_ANYCRLFを設定することにより、CR、LF、またはCRLFのみ(Unicodeラインエンディングの完全なセットの代わりに)のみを制限することができます。 (BSRは「バックスラッシュr」の略語です。)これは、PCREが構築されたときにデフォルトにすることができます。この場合、PCRE_BSR_UNICODEオプションを介して他の動作を要求できます。また、次のシーケンスのいずれかでパターン文字列を起動することにより、これらの設定を指定することもできます。
(*BSR_ANYCRLF) CR, LF, or CRLF only (*BSR_UNICODE) any Unicode newline sequence
これらは、pcre_compile()またはpcre_compile2()に与えられたデフォルトとオプションをオーバーライドしますが、pcre_exec()またはpcre_dfa_exec()に与えられたオプションによってオーバーライドできます。これらの特別な設定は、perl互換ではないが、パターンの開始時にのみ認識されており、それらは大文字でなければならないことに注意してください。それらのうちの複数が存在する場合、最後のものが使用されます。それらは、Newline Conventionの変更と組み合わせることができます。たとえば、パターンは以下で始めることができます。
(*ANY)(*BSR_ANYCRLF)
また、(*utf8)または(*ucp)特別なシーケンスと組み合わせることもできます。キャラクタークラス内では、 rは認識されていないエスケープシーケンスとして扱われるため、デフォルトで「R」という文字に一致しますが、PCRE_EXTRAが設定されている場合はエラーが発生します。
他のヒント
新しいラインを正規化するには、私が常に使用しています:
$str = preg_replace('~\r\n?~', "\n", $str);
それは古いMacを置き換えます(\r
)そして窓(\r\n
)UNIX同等のニューライン(\n
).
使用して事前にフィーフします \n
2つではなく1つのバイトしかかからないからですが、簡単に変更できます \r\n
.
どうですか
$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
CRLFに変換する最も賢い/最も簡単な方法は、次のとおりです。
$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));
LFのみに変換するには:
$output = str_replace("\r", '', $input);
正規表現よりもはるかに簡単です。