ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

我注意到

Regex101 仅在 \n 上匹配换行符(例如 - 删除 \r 并且它匹配)

RegExr 既不在 \n 也不在 \r\n 上匹配换行符,除了 m-flag 和 \s (示例)之外,我找不到使其匹配换行符的东西

Debuggex 的行为更加不同:在此示例中,它仅在 \r\n 上匹配,而在这里它仅在 \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 个字符)。

A
Aryan Beezadhur

我会反方向回答。

有关 \r 和 \n 的完整解释,我必须参考这个问题,这个问题比我在这里发布的要完整得多:\n 和 \r 之间的区别?

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

Ilya 建议的 [\r\n]+ 将起作用,但也会匹配多个连续的换行符。 (\r\n|\r|\n) 更正确。


实际上,因为在您的第三个示例(Senior men's ...)中,文本中有一个 \r\n(如果您右键单击并显示源代码,您会在某处找到 {{Infobox XC Championships\r\n|Name =)。第二个工具是用 Flash 编写的,当您阅读 about-page 时,换行符有点错误。
(\r\n|\r|\n) 可以更简单地写成 \r\n?
@AsadSaeeduddin 不,它不能。它与 Unix 行尾 \n 不匹配
哎呀,你是对的。我的意思是将 ? 添加到 \r,这是可选的。它应该是 \r?\n
@AsadSaeeduddin 那一个与 Mac 的单曲 \r 不匹配
T
Toto

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


@Sandwell:对不起,我没听懂,这不是问题,而是答案,比 (\r\n|\r|\n) 简单
D
Dane

在 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,在那里被误导了!
K
Keelung

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

佚名

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

K
Kepi

聚会有点晚了,但对于其余的人来说可能有用。在 javascript 中,您也可以简单地编写管道 (|) 来匹配换行符/换行符。就我而言,我需要去掉所有的逗号、分号和空格字符(包括换行符),所以我最终使用了这个:

.split(/[\s,;|]+/)


r
rufreakde

不确定这是否是所要求的:

(somethingToStaMatch)(.|\n)*?(somethingToEndMatch)

这将有 3 组比赛。而 ALLWITHLINEBREAKS 位于中间。可能会帮助使用 dotnet 进行测试的人。

字符串模式 = @"(somethingToStartMatch)(.|\n)*?(somethingToEndMatch)";

请注意,即使您的文本有多个关键字对,*? 也允许匹配!