正则表达式:标志与替换
标志(flags)改变匹配器的行为,例如是否忽略大小写、是否跨行处理。替换则将找到的结果改写成新文本。本篇用 JavaScript 字面量 /模式/标志 直观展示常见字母,再在下一课映射到 Python 与 PowerShell API;不要把字面量语法直接复制进 Python。
标志不是完全通用
g是 JavaScript 中“继续查找”的标志;Python 更常通过findall、finditer或sub这类 API 获取全部结果。i、m、s在许多引擎中存在,但名称、内联写法与 Unicode 细节可能不同。PowerShell 的-match默认忽略大小写,若契约区分大小写应使用-cmatch。
1. 全局匹配:g
功能说明
在 JavaScript 中,g 让匹配 API 或替换 API 继续查找后续结果,而不是只处理第一个命中。是否真正返回全部结果还与所调用的方法有关,例如 matchAll 和 replace 的行为不同于 test。
语法格式
/模式/g简单示例
"id=12; id=34".match(/\d+/g)匹配结果说明
结果为 ['12', '34']。移除 g 后,match(/\d+/) 通常只返回第一个数字 12 及其附加匹配信息。Python 中可用 re.findall(r'\d+', text) 获取同样的两个结果。
2. 忽略大小写:i
功能说明
i 让字母匹配时不区分大小写。它主要用于英文等大小写有差异的文字;Unicode 字母的大小写折叠规则比 ASCII 更复杂,跨语言数据需要使用目标引擎测试。
语法格式
/模式/i简单示例
"Error ERROR error".match(/error/gi)匹配结果说明
结果为 ['Error', 'ERROR', 'error']。g 负责找到所有结果,i 负责忽略字母大小写;没有 i 时,模式 error 只会匹配最后一个小写实例。
3. 多行模式:m
功能说明
m 改变 ^ 和 $ 的含义:它们除了匹配整个输入的开始与结束,也能匹配每一行的开始与结束。多行模式不会让点号 . 自动跨越换行,跨行匹配由单行(dotAll)模式控制。
语法格式
/^模式$/m简单示例
"ok\nERROR: disk full\nok".match(/^ERROR:.*$/m)匹配结果说明
结果是 ERROR: disk full。没有 m 时,^ 与 $ 只约束整个三行字符串,因此这条居中的错误行不会匹配。
4. 单行模式(dotAll):s
功能说明
s 常被称为单行模式或 dotAll 模式:它让点号 . 也能匹配换行符。名称中的“单行”容易误导,它不改变 ^ 和 $ 的行为;后者仍要使用 m。
语法格式
/开始.*结束/s简单示例
"<p>第一行\n第二行</p>".match(/<p>.*<\/p>/s)匹配结果说明
结果是整个 <p>第一行\n第二行</p> 片段。没有 s 时,点号无法越过换行,模式不匹配。对于 HTML、JSON 等有嵌套结构的文本,正则只能用于受控的小片段,不能代替真正的解析器。
5. 正则表达式替换
功能说明
替换操作先用正则找到目标,再用指定文本或函数生成新内容。它常用于规范空白、脱敏、批量修改格式。替换前应先检查匹配结果,并尽量在副本或测试数据上运行。
语法格式
文本.replace(/模式/g, "替换文本")简单示例
"姓名 年龄\t城市".replace(/\s+/g, " ")匹配结果说明
结果为 姓名 年龄 城市。\s+ 找到每一段连续空白,g 确保全部替换成一个普通空格。若移除 g,通常只会替换第一段连续空白。
6. 捕获组在替换中的使用
功能说明
替换文本可以引用捕获组,从而重排、保留或格式化已匹配的子内容。JavaScript 替换字符串中常用 $1、$2;Python 常用 \g<1>、\g<2>,不要混用两种语法。
语法格式
文本.replace(/(组1)(组2)/g, "$2$1")简单示例
"日期:2026-07-12".replace(/(\d{4})-(\d{2})-(\d{2})/g, "$3/$2/$1")匹配结果说明
结果为 日期:12/07/2026。正则先把年、月、日分别捕获为第 1、2、3 组,再按“日/月/年”的顺序写入替换文本。若使用命名捕获组,JavaScript 可通过 $<name> 引用,读起来通常更清晰。
7. 常用匹配模式的边界意识
功能说明
常用模式常用于初步结构筛选,例如整数、简易邮箱或版本号。但“看起来像”不等于“业务上有效”:邮箱可投递性、日期存在性、电话号码归属等都需要额外验证,不应只依赖正则。
语法格式
整数:^-?\d+$
简单版本号:^\d+\.\d+\.\d+$
简易邮箱结构:^[^\s@]+@[^\s@]+\.[^\s@]+$简单示例
^\d+\.\d+\.\d+$测试文本:1.2.3、v1.2.3、1.2、1.2.3.4
匹配结果说明
只有 1.2.3 匹配,因为它由恰好三段数字组成,并用句点分隔。它不判断版本号范围或语义;例如 999.999.999 在结构上仍会匹配。
练习与自测
- 解释
m与s分别改变什么;为什么“多行”不等于“点号跨行”? - 在 Python 中用
re.MULTILINE找出所有以ERROR:开头的行,再用finditer输出行内位置。 - 分别写出 JavaScript、Python 和 PowerShell 的“把连续空白替换为一个空格”,标注替换引用语法差异。
- 用函数替换将每个数字加一;说明为什么复杂替换逻辑不应硬塞进替换字符串。
- 为简易版本号模式补充最大段长度,并说明结构校验与版本语义校验的边界。
上一节:先行与后行断言|下一节:Python re 与 PowerShell 实用 API。