匹配换行符-\ n或\ r \ n?


159

在写此答案时,我必须完全匹配换行符,而不是使用s-flag(dotall -点匹配换行符)。

尝试匹配\n或时,通常用于测试正则表达式的网站的行为会有所不同\r\n

我注意到

  • Regex101仅与上的换行符匹配\n
    示例 -删除\r并匹配)

  • RegExr匹配换行符既不\n 也不\r\n
    ,我无法找到的东西,使之匹配断行,除了m-flag和\s
    例如

  • Debuggex的行为更加不同:
    此示例\r\n,它仅与匹配,而
    此处仅与匹配\n,并且指定了相同的标志和引擎

我完全知道m-flag(多行-使^匹配行的开头和$结尾),但是有时这不是一个选择。与相同\s,因为它也匹配制表符和空格。

我认为使用unicode换行符(\u0085)失败,因此:

  1. 有没有一种故障保险方法,可以将换行符上的匹配项(无论使用哪种语言,最好都集成到正则表达式中)?
  2. 上述网站为什么不同的表现(尤其是Debuggex,一旦匹配只有\n一次只\r\n)?

15
你可以试试[\r\n]+-或这样的事情
伊利亚Bursov

3
我用:\r?\n同时匹配\r\n\n线路终止序列。它不适用于旧的\rMac语法,但是如今这种语法很少见。
ridgerunner

6
嘿,我是debuggex的创始人。这看起来像个错误(对于debuggex,我不能代表其他人)。我添加了一个高优先级的问题,引用了这个问题。我们将尽快解决它-我们目前将所有(非常有限的)资源集中在发布另一种产品上。
Sergiu Toarca 2013年

2
@ridgerunner可以在其中添加Mac的语法,您可以执行(\ r?\ n | \ r),类似于下面的Peter van der Wal的回答,但更紧凑(10个字符对12个字符)。
Doktor J

Answers:


220

会反方向回答。

2)有关这个问题的完整说明\r\n我必须参考这个问题,这个问题比我在此处发布的要完整得多:\ n和\ r之间的区别?

长话短说,Linux \n用于新的Windows \r\n和旧版Mac \r。因此,可以通过多种方式编写换行符。例如,您的第二个工具(RegExr)在单个工具上匹配\r

1)[\r\n]+按照Ilya的建议可以使用,但也可以匹配多个连续的换行符。(\r\n|\r|\n)更正确。


因此,\r/ \n取决于操作系统-这可能是人们所知道的(;))-但是为什么两个debuggex示例在\ r \ n上一次匹配,而在\ n上一次匹配呢?至少对我而言,在示例中没有区别。
KeyNone

最可能的原因是您将其中一个复制到Windows文本编辑器中,而另一个则直接写入debuggex文本区域中。每个使用不同的换行符。
OGHaza

1
确实,因为在您的第三个示例(高级男士...)中 \r\n中,文本中(如果右键单击并显示源代码,您将在{{Infobox XC Championships\r\n|Name =某个地方找到)。第二个工具是用Flash编写的,当您阅读“关于”页面时,换行符会出现一些问题。
彼得·范德沃尔

1
(\r\n|\r|\n) 可以更简单地写为 \r\n?
阿萨德Saeeduddin

2
@AsadSaeeduddin不行。它不会匹配的Unix行结束\n
彼得·范德沃尔玛

12

在Debuggex的示例文本中,您具有不同的行尾。特别有趣的是,Debuggex似乎已经确定了您首先使用的行尾样式,并将所有其他输入的行尾转换为该样式。

我使用Notepad ++将Unix和Windows格式的示例文本粘贴到Debuggex中,首先粘贴的是Debuggex会话所粘贴的内容。

因此,在将文本粘贴到Debuggex中之前,应先通过文本编辑器清洗文本。确保您要粘贴所需的样式。Debuggex默认为Unix样式(\ n)。

此外,NEL(\ u0085)完全不同:https://en.wikipedia.org/wiki/Newline#Unicode

(\r?\n)将涵盖Unix和Windows。您需要更复杂的东西,例如(\r\n|\r|\n)如果您也想匹配旧的Mac,则。


关于debuggex的非常有趣的一点!另外,感谢您指出\ u0085,在那里误导了您!
KeyNone

3

在PCRE \R比赛中\n\r\r\n


毫无疑问
Sandwell '18

1
@Sandwell:对不起,我不明白你的意思,这不是一个问题,而是一个答案,比(\r\n|\r|\n)
Toto

2

这仅适用于问题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" );
 }

2

在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()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.