web-dev-qa-db-ja.com

PHP最も賢い方法で異なる改行スタイルを置き換える方法は?

改行スタイルが異なる可能性のあるテキストがあります。すべての改行 '\ 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つの置換ではこれを実行できないことです。

ご協力ありがとうございました!

36
Deckard
$string = preg_replace('~\R~u', "\r\n", $string);

すべてのUnicode改行を置き換えたくないが、CRLFスタイルの改行のみを置き換えたい場合は、以下を使用します。

$string = preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $string);

\Rはこれらの改行に一致し、uは入力文字列をUTF-8として扱うための修飾子です。


PCRE docs から:

\R一致

デフォルトでは、パターン内のシーケンス\ Rは、行末シーケンスとして選択されているものに関係なく、すべてのUnicode改行シーケンスに一致します。指定した場合

     --enable-bsr-anycrlf

デフォルトは、\ RがCR、LF、またはCRLFのみに一致するように変更されています。 PCREのビルド時に選択されたものは、ライブラリ関数が呼び出されたときにオーバーライドできます。

そして

改行シーケンス

文字クラスの外では、デフォルトで、エスケープシーケンス\ RはすべてのUnicode改行シーケンスと一致します。非UTF-8モードでは、\ Rは次と同等です。

    (?>\r\n|\n|\x0b|\f|\r|\x85)

これは「原子グループ」の例であり、その詳細を以下に示します。この特定のグループは、LFが後に続く2文字のシーケンスCR、または単一文字のいずれかと一致しますLF(改行、U + 000A)、VT(垂直タブ、U + 000B)、FF (formfeed、U + 000C)、CR(キャリッジリターン、U + 000D)、またはNEL(次の行、U + 0085)。2文字のシーケンスは、分割できない単一のユニットとして扱われます。

UTF-8モードでは、コードポイントが255を超える2つの追加文字が追加されます:LS(行区切り、U + 2028)およびPS(段落区切り、U + 2029)。これらの文字を認識するために、Unicode文字プロパティのサポートは必要ありません。

コンパイル時またはパターンが一致したときにオプションPCRE_BSR_ANYCRLFを設定することにより、\ Rを制限して、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互換ではないこれらの特別な設定は、パターンの最初にのみ認識され、大文字でなければならないことに注意してください。それらが複数存在する場合は、最後のものが使用されます。これらは、改行規則の変更と組み合わせることができます。たとえば、パターンは次のように開始できます。

    (*ANY)(*BSR_ANYCRLF)

(* UTF8)または(* UCP)特殊シーケンスと組み合わせることもできます。文字クラス内では、\ Rは認識されないエスケープシーケンスとして扱われるため、デフォルトでは文字 "R"と一致しますが、PCRE_EXTRAが設定されている場合はエラーが発生します。

88
NikiC

改行を正規化するために常に使用します:

$str = preg_replace('~\r\n?~', "\n", $str);

古いMac(\r)とWindows(\r\n)の改行を、Unixの同等の(\n)に置き換えます。

2バイトではなく1バイトしか必要ないため、\nの使用を推奨しますが、\r\nに簡単に変更できます。

15
Alix Axel

いかがですか

$sNicetext = preg_replace('/\r\n|\r|\n/', "\r\n", $sNicetext);
9
Tomalak

cRLFに変換する最も賢い/最も簡単な方法は次のとおりです。

$output = str_replace("\n", "\r\n", str_replace("\r", '', $input));

LFのみに変換する:

$output = str_replace("\r", '', $input);

正規表現よりもはるかに簡単です。

2
Roey