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

Posted

技术标签:

【中文标题】匹配换行符 - \\n 或 \\r\\n?【英文标题】:Match linebreaks - \n or \r\n?匹配换行符 - \n 或 \r\n? 【发布时间】:2013-12-02 02:32:48 【问题描述】:

在编写this answer 时,我必须只匹配换行符,而不是使用s-标志(dotall - 点匹配换行符)。

通常用于测试正则表达式的网站在尝试匹配 \n\r\n 时表现不同。

我注意到了

Regex101 仅匹配 \n 上的换行符 (example - 删除 \r 并且匹配)

RegExr 匹配 \n 上的换行符 既不 也不 \r\n 除了 m-flag 和 \s (example)

Debuggex 的行为更加不同: 在this example 中,它只匹配\r\n,而here 它只匹配\n,并指定了相同的标志和引擎

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

我想使用 unicode 换行符 (\u0085) 没有成功,所以:

    是否有故障安全方法将换行符上的匹配项(最好不管使用何种语言)集成到正则表达式中? 为什么上述网站的行为不同(尤其是 Debuggex,只在 \n 上匹配一次,在 \r\n 上只匹配一次)?

【问题讨论】:

你可以试试[\r\n]+ - 或者类似的东西 我使用:\r?\n 来匹配\r\n\n 行终止序列。它不适用于旧的 \r Mac 语法,但如今这种语法非常罕见。 大家好,我是 debuggex 的创始人。这看起来像一个错误(对于 debuggex,我不能代表其他人)。我添加了一个引用这个问题的高优先级问题。我们会尽快解决这个问题 - 我们目前正将所有(非常有限的)资源集中在推出另一款产品上。 @ridgerunner 添加 Mac 的语法,你可以这样做 (\r?\n|\r),这类似于下面 Peter van der Wal 的答案,但更紧凑(10 个字符对 12 个字符)。 【参考方案1】:

在 PCRE 中,\R 匹配 \n\r\r\n

【讨论】:

@Sandwell:对不起,我没听懂,这不是问题,而是答案,比(\r\n|\r|\n)简单【参考方案2】:

会反方向回答。

2) 有关\r\n 的完整解释,我必须参考这个问题,它比我在这里发布的要完整得多:Difference between \n and \r?

长话短说,Linux 使用 \n 换行,Windows 使用 \r\n 和旧 Mac 使用 \r。所以有多种方法可以编写换行符。例如,您的第二个工具 (RegExr) 与单个 \r 匹配。

1) [\r\n]+ 正如 Ilya 建议的那样可以工作,但也会匹配多个连续的换行符。 (\r\n|\r|\n) 更正确。

【讨论】:

所以,\r/\n 取决于操作系统 - 这是人们可能知道的事情 (;)) - 但为什么两个 debuggex-examples 在 \r\n 上匹配一次一次在\n上?至少对我来说没有区别(在示例中)。 确实,因为在您的第三个示例(Senior men's ...)中,文本中有一个\r\n(如果您右键单击并显示源代码,您会在某处找到Infobox XC Championships\r\n|Name =) .第二个工具是用 Flash 编写的,当您阅读 about-page 时,换行符有点错误。 (\r\n|\r|\n) 可以更简单地写成\r\n? @AsadSaeeduddin 不,它不能。它与 Unix 行尾 \n 不匹配 @AsadSaeeduddin 那一个与 Mac 的单曲不匹配 \r【参考方案3】:

在 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()

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

我使用 Notepad++ 将 Unix 和 Windows 格式的示例文本粘贴到 Debuggex 中,无论我先粘贴的是哪个 Debuggex 会话。

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

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

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

【讨论】:

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

以上是关于匹配换行符 - \n 或 \r\n?的主要内容,如果未能解决你的问题,请参考以下文章

如何用 <br/> 替换换行符或 \r\n?

正则表达式

正则表达式的一些符号

正则表达式 怎么插入换行

正则表达式删除新行和空格

Qt正则表达式