正则匹配文本文件中的 3 种换行符 (行尾)

讨论

错误示范:

  • 错误示范 1:\n —— 不匹配 Windows 行尾(CRLF);
  • 错误示范 2:\r\n|\n —— 不匹配旧式 mac 行尾(CR);
  • 错误示范 3:[\r\n]{1,2} —— 错误匹配“LFCR”;
  • 错误示范 4:\r?\n —— 不匹配旧式 mac 行尾(CR);
  • 错误示范 5:\n|\r|\r\n —— CR 和 LF 被拆开,如果存在 CRLF 将匹配出两个子串;
  • 错误示范 6:\r\n?|\n —— 这个的 bug 很难发现,问题在于:如果文件中存在 LFCRLF,则 LF 和 CRLF 都被匹配,但这种情况下应该只有 CRLF 才对;
  • 错误示范 7:\r\n|\n|\r —— 问题同上。

正确示范:\r?\n|(?<!\n)\r —— 使用零宽断言。

这个正则 永远不会匹配到 LFCR;但也有弱点,即 LFCRLF 会匹配两个子串:LF 和 CRLF;但对于长度不大于 2 的纯 LF、CR 序列,都能够正确匹配。

所以就有了更正确一些的示范:\r\n|(?<!\r\n)\n(?!\r\n)|(?<!\r\n|\n)\r(?!\r\n|\n) —— 看起来很长但思路很简单:

  1. 优先匹配 CRLF;
  2. 否则,匹配前后都没有 CRLF 的 LF;
  3. 否则,匹配前后都没有 CRLF 或 LF 的 CR。
  4. 否则,拒绝。

(你也可以调整单独 CR 和单独 LF 的优先级,但 CRLF 的优先级总是最高的)

当存在长度小于等于 3 的纯 LF、CR 构成的序列时,这个正则都能给出正确的匹配,但 LFCRCR 除外,它会匹配两个子串,即 LF 和末尾的 CR;为了解决这个问题就必须进一步增加规则。

我们发现,这样下去是没完没了的……正则表达式的长度取决于你要实现正确匹配的纯 LF、CR 序列的最大长度。

结论

对于不那么极端的情况,\r?\n|(?<!\n)\r 就可以正确匹配了。

抬杠

任何有限长的正则表达式 RRR 都无法正确匹配任意无限长的序列 SSS 中可接受的子串 σR(S)\sigma_R(S)σR(S)Σ\SigmaΣΣ\SigmaΣ 是所有可接受的子串集合,且 card(Σ)>1card(\Sigma) > 1card(Σ)>1),使匹配到的子串集合 card(Σ′)=1card(\Sigma ') = 1card(Σ)=1.

<think>我们正在讨论正则表达式换行符的表示方法。根据提供的引用,我们可以总结如下:1.在正则表达式中,普通点号`.`默认不匹配换行符(`\n`)[^1][^3]。2.要匹配换行符,可以使用:-直接使用`\n`来表示换行符(但需要注意转义,在某些语言中可能需要双反斜杠`\\n`)。-使用字符类,例如`[\s\S]`,因为`\s`匹配所有空白字符(包括换行符),而`\S`匹配所有非空白字符,所以`[\s\S]`可以匹配任意字符,包括换行符[^1][^3]。-同样,`[\d\D]`、`[\w\W]`等也可以达到同样的效果。3.另外,在Python中,可以使用`re.DOTALL`(或`re.S`)标志,使点号`.`匹配包括换行符在内的所有字符[^3]。因此,正则表达式换行符可以直接用`\n`表示。而如果要匹配任意字符(包括换行符),可以使用`[\s\S]`或启用对应的修饰符。下面我们具体说明:###1.直接匹配换行符`\n`如果目标就是匹配一个换行符,那么直接写`\n`即可。例如,在字符串匹配一个换行符正则表达式为:`\n`。###2.匹配包括换行符的任意字符如果我们希望匹配任意字符,包括换行符,有以下几种方法:-使用字符类:`[\s\S]`、`[\d\D]`、`[\w\W]`等。例如,匹配任意多个字符(包括换行符)可以写:`[\s\S]*`。-使用修饰符(也称为标志)让点号`.`匹配换行符:-在JavaScript中,可以使用`s`修饰符(ES2018引入),例如:`/.*/s`。-在Python中,使用`re.DOTALL`或`re.S`,例如:`re.compile(&#39;.*&#39;,re.S)`。###示例假设我们有一段文本:```第一行第二行```我们想要匹配从“第一行”到“第二行”的整个字符串(包括换行符)。-使用`\n`匹配换行符:我们可以用`第一行\n第二行`来匹配。-使用`[\s\S]`匹配任意字符:我们可以用`第一行[\s\S]*?第二行`来匹配(非贪婪模式)。###在不同编程语言中的使用-**JavaScript**:```javascript//匹配换行符letregex1=/\n/;//匹配任意字符(包括换行符)的方法1:使用[\s\S]letregex2=/第一行[\s\S]*?第二行/;//方法2:使用s修饰符(ES2018+)letregex3=/第一行.*?第二行/s;```-**Python**:```pythonimportre#匹配换行符pattern1=r&#39;\n&#39;#使用[\s\S]匹配任意字符pattern2=r&#39;第一行[\s\S]*?第二行&#39;#使用re.S让点号匹配换行符pattern3=re.compile(r&#39;第一行.*?第二行&#39;,re.S)```###注意事项-在正则表达式中,换行符是`\n`,但在不同的操作系统中换行符可能不同(Windows使用`\r\n`)。因此,如果需要匹配跨平台的换行,可能需要考虑`\r?\n`。-在字符类中,`\n`可以直接使用,例如`[\n]`表示匹配换行符,但通常我们不会单独这样用。综上所述,正则表达式换行符的表示方法为`\n`,而匹配任意字符(包括换行符)则可以使用`[\s\S]`或相应的修饰符。§§相关问题§§1.正则表达式中如何匹配回车符(`\r`)?2.在不同编程语言中如何使用正则表达式匹配多行文本?3.正则表达式中`.`不能匹配哪些字符?4.如何使用正则表达式匹配一段包含换行的多行注释?</think>### 正则表达式换行符的表示方法 在正则表达式中,换行符的表示主要有以下几种方式: 1. **直接使用 `\n`** 这是最标准的表示方法,`\n` 在正则中明确匹配换行符(ASCII 0x0A)。 示例:`/start\nend/` 匹配 "start" 后紧跟换行符再跟 "end" 的文本。 2. **使用字符集 `\s`** `\s` 匹配**所有空白字符**,包括:空格、制表符(`\t`)换行符(`\n`)、回车符(`\r`)、垂直制表符等。 示例:`/\s+/` 匹配连续的空白字符(包含换行符)。 3. **使用互补字符集 `[\s\S]`** 这是匹配**任意字符(含换行符)** 的常用技巧: - `\s` 匹配所有空白字符(含`\n`) - `\S` 匹配所有非空白字符 - `[\s\S]` 组合相当于通配符 `.` 的增强版 示例:`/<div>[\s\S]*?<\/div>/` 匹配多行`<div>`标签内容。 4. **启用修饰符(匹配模式)** 通过修饰符强制 `.` 匹配换行符: - **JavaScript**: `/regex/s` 中的 `s` 标志(dotAll 模式) - **Python**: `re.DOTALL` 或 `re.S` 标志 - **Java**: `Pattern.DOTALL` 示例(Python): ```python re.findall(r&#39;start(.*?)end&#39;, text, re.S) # . 可匹配换行符 ``` --- ### 关键注意事项 1. **`.` 默认不匹配换行符** 正则中的点号 `.` 默认匹配**除换行符外**的任何字符([^1][^3])。这是多行匹配失败的常见原因。 2. **操作系统差异** - Unix/Linux: 换行符 = `\n` (LF) - Windows: 换行符 = `\r\n` (CRLF) 跨平台匹配建议:`\r?\n` 3. **行首/行尾锚点** - `^` 匹配行首(在 `/m` 多行模式下) - `$` 匹配行尾(在 `/m` 多行模式下) --- ### 应用示例 ```javascript // JavaScript 匹配多行注释(含换行符) const regex = /\/\*[\s\S]*?\*\//gm; ``` ```python # Python 提取多行HTML内容 import re html = "<div>Hello\nWorld</div>" re.findall(r&#39;<div>([\s\S]*?)</div>&#39;, html) # 输出: [&#39;Hello\nWorld&#39;] ``` > ⚠️ 当需要匹配包含换行符的内容时,优先选择 `[\s\S]` 或启用 `s/DOTALL` 模式,避免使用原始点号 `.`[^3][^4]。
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值