匹配换行符 - \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?的主要内容,如果未能解决你的问题,请参考以下文章