web-dev-qa-db-ja.com

改行を一致させる - \ nまたは\ r \ n?

この答えを書いている間 s-フラグを使うのではなく、改行のみで一致させる必要がありました(dotall - dotは改行に一致します)。

通常、正規表現のテストに使用されているサイトは、\nまたは\r\nで一致させようとしたときの動作が異なります。

私は気づきました

  • Regex101は\nでのみ改行に一致します
    - \rを削除して一致します)

  • RegExrは改行に一致します\n\r\nも一致しません
    そしてm- flagと\sを除いて、改行に一致させるものが見つかりません。

  • Debuggexの動作はさらに異なります。
    この例では これは\r\nでのみ一致しますが、
    ここで 同じフラグとエンジンを指定して、\nでのみ一致します

私はm-フラグ(multiline - ^を行頭と$を行末に一致させる)を完全に認識していますが、時々これは選択肢ではありません。タブとスペースにも一致するので、\sと同じです。

Unicodeの改行文字( \u0085 )を使用するという私の考えは成功しませんでした。

  1. 改行での一致を(使用する言語に関係なく)正規表現に統合するためのフェイルセーフな方法はありますか?
  2. なぜ上記のサイトは異なった振る舞いをするのでしょうか(特にDebuggex、\nと一度だけ\r\nにマッチする)。
108
Basti M

反対方向に返事をするつもりです。

2)\ rと\ nについての完全な説明については、この質問を参照する必要があります。これは、ここで投稿するよりもはるかに完全です。 \ nと\ rの違いは?

長い話を簡単に言えば、Linuxは改行にWindowsを使い、Windowsと古いMacを使います。そのため、改行を書くには複数の方法があります。あなたの2番目のツール(RegExr)は、例えば単一の\ rにマッチします。

1)Ilyaが提案した[\r\n]+は動作しますが、複数の連続する改行にも一致します。 (\r\n|\r|\n)はもっと正しいです。

149

Debuggexのサンプルテキストでは、行末が異なります。特に興味深いのは、Debuggexが最初に使用した行末スタイルを識別しているようで、入力されたすべての追加の行末スタイルがそのスタイルに変換されることです。

私はUnixとWindowsフォーマットのサンプルテキストをDebuggexに貼り付けるためにNotepad ++を使いました、そして最初に貼り付けたものがDebuggexのそのセッションが動かなかったものです。

そのため、Debuggexに貼り付ける前に、テキストエディタでテキストを洗い流す必要があります。あなたが望むスタイルを貼り付けていることを確認してください。 DebuggexのデフォルトはUnixスタイル(\ n)です。

また、NEL(\ u0085)はまったく異なるものです。 https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)はUnixとWindowsをカバーします。昔のMacにも合わせたいのなら、(\r\n|\r|\n)のようにもっと複雑なものが必要です。

7
Dane

これは質問1にのみ適用されます。

Windows上で動作し、複数行のMFCエディタボックスを使用するアプリがあります。
エディタボックスにはCRLFの改行が必要ですが、入力されたテキストを解析する必要があります。
いくつかの非常に大きくて厄介な正規表現があります。

正規表現を書いている間、私はこれについて強調したくありませんでした。
私は、パーサーとエディターの間で行ったり来たりして正規化することにしました。
正規表現は\nを使うだけです。また、貼り付け操作をトラップしてボックスに変換します。

これはあまり時間がかかりません。
これが私が使っていることです。

 boost::regex  CRLFCRtoLF (
     " \\r\\n | \\r(?!\\n) "
     , MODx);

 boost::regex  CRLFCRtoCRLF (
     " \\r\\n?+ | \\n "
     , MODx);


 // Convert (All style) linebreaks to linefeeds 
 // ---------------------------------------
 void ReplaceCRLFCRtoLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoLF, "\\n" );
 }

 // Convert linefeeds to linebreaks (Windows) 
 // ---------------------------------------
 void ReplaceCRLFCRtoCRLF( string& strSrc, string& strDest )
 {
    strDest  = boost::regex_replace ( strSrc, CRLFCRtoCRLF, "\\r\\n" );
 }
1
sln

Pythonでは:

# as Peter van der Wal's answer
re.split(r'\r\n|\r|\n', text, flags=re.M) 

より厳密な

# https://docs.python.org/3/library/stdtypes.html#str.splitlines
str.splitlines()
0
Keelung