让点号吃换行
单行模式又叫点号匹配换行模式:打开之后,点号把换行符也当作普通字符对待,可以跨行匹配。它是控制点号行为的唯一开关,与多行模式管理的锚点是两回事。
名字的误导
名称里的「单行」说的是它让整段文本被当作一行看待,而不是让模式只匹配一行。理解方式:单行模式把多行文本在点号眼里压成一行,多行模式把一段文本在锚点眼里拆成多行。
基本信息
| 作用对象 | 仅改变点号的换行行为 |
|---|---|
| 不改动的部分 | 锚点位置判定、量词贪婪策略、字符类内容 |
| Python 写法 | re.DOTALL 或内联修饰符 (?s) |
| JavaScript 写法 | 模式后加 s 标志 |
| Java 与 .NET | Pattern.DOTALL、RegexOptions.Singleline |
| 等效替代 | 用任意字符的显式集合代替点号,不依赖开关 |
| 组合使用 | 可与多行模式同时开启,分别管点号与锚点 |
典型使用场景
- 跨行提取被多行包裹的代码块、配置段或日志堆栈
- 匹配跨段落出现的成对标记之间的内容
- 处理从文件整体读入的文本,需要忽略其中的换行
- 校验跨行文本结构,例如成对括号跨越换行
- 在单行数据上无需该开关,避免误用过宽的点号
跨行匹配的写法
跨行匹配的写法
rg -U 'START(?s:.*?)END' f.txt # 开启多行匹配能力后跨行提取
rg -U '(?s).*' f.txt # 点号匹配换行,配合量词取整段
perl -0777 -ne 'print $1 if /(A.*?B)/s' f.txt # 一次读入整文件再匹配
sed -n '/START/,/END/p' f.txt # 用行区间代替跨行正则,更直观
awk '/START/{f=1} f{print} /END/{f=0}' f.txt # 状态机写法,结果可控
rg -U 'START[\s\S]*?END' f.txt # 不依赖开关的显式字符集合写法两个开关的分工
| 开关 | 改变点号 | 改变锚点 |
|---|---|---|
| 单行模式 | 匹配换行 | 无影响 |
| 多行模式 | 无影响 | 逐行生效 |
| 同时开启 | 匹配换行 | 逐行生效 |
| 都不开 | 不匹配换行 | 只认整段首尾 |
很多命令行工具默认逐行处理文本,单行标志只是让工具在跨行模式下的模式语义正确,并不会自动把整个文件一次读入。真正需要跨行匹配时,还要确认输入是按整段送入引擎的。
打开点号跨行后,原本靠换行天然形成边界的模式会失效,配合贪婪量词极易吃满整段文本。跨行提取建议同时使用非贪婪量词或显式字符集合,把范围限制住。