Notepad++ 正则替换完全指南:15 个实例 + 宏与脚本自动化
Notepad++ 正则替换的操作只有三步:按 Ctrl+H 打开替换窗口 → 搜索模式选「正则表达式」→ 填查找串和替换串,捕获组用 (...) 括起来,替换串里用 \1、\2 引用。难点不在操作,在你有没有选对搜索模式——我见过的"正则不生效",九成栽在这一步,还有一成栽在 Windows 文档的换行其实是两个字符。
前阵子要改一份 500 行的建表脚本,给每条 CREATE TABLE 前面补一句 DROP TABLE IF EXISTS。手工干就是复制粘贴 500 次,四十分钟起步,中途走神一次还得重来;写成一条正则,八秒钟。这类活的共同点是:量大人肉扛不住,但规则是固定的。规则固定,机器就能干。
下面所有操作在 Notepad++ 中文版 的默认安装下都能复现,不需要额外插件,涉及插件的章节我会单独标注。版本以 8.x 为准,更老的版本(7.8 及以前)个别写法会有差异,文中会点出来。
这篇写完你能拿到三样东西:15 条从真实工作里长出来的正则,每条都能直接抄;一套不会把文件改坏的操作纪律;以及一条往上走的路:什么时候该录宏,什么时候该上脚本。
安全声明:批量替换是不可逆的。本文每条正则都标了风险等级和"先试跑"的位置,跟着做不会毁文件。就算这样,动手前还是请另存一份。
关键要点 - Notepad++ 有三种搜索模式,正则模式下「全字匹配」会被自动取消勾选并灰掉,「向上搜索」默认也不可用,这是官方行为不是 bug。 - 反向引用在 Notepad++ 里写
\1、\2。Boost 正则引擎认这个写法,全文统一用它。 - Windows 文档的换行是\r\n两个字符,只匹配\n会剩下孤立的\r,看起来就像"替换没生效"。跨平台通吃写\R(7.9 起完整支持)。 - 替换串里可以用\U/\L/\E控制大小写,靠它做下划线与驼峰互转,比手敲大写字母可靠得多。 - 15 个案例全部配齐"查找串 / 替换串 / 替换前 / 替换后"四件套,复制即可用,不需要截图对照。 - 正则做不到条件判断和跨文件循环,那两类活交给宏和 Python Script,文末有一张决策表。
一、三种搜索模式:正则不生效,多半是模式选错了
这一段解决"我照着教程敲了正则,为什么一点反应都没有"。答案通常不是正则写错,是搜索模式不对。
Ctrl+F(查找)和 Ctrl+H(替换)窗口的左下角有一组单选框,就是搜索模式。三个选项,能力差得很远。
普通模式(Normal):所有字符按字面处理。你在查找框输入的每一个字符,包括反斜杠,都被当成普通文本。想找 \d 这两个字符本身,就用它。
扩展模式(Extended):只有一组固定的转义生效——\n(LF)、\r(CR)、\t(Tab)、\0(空字符)、\\(反斜杠本身),外加 \x20(十六进制字节)、\o040(八进制)、\d032(十进制)、\u263A(Unicode 码位)这类"按码位找字符"的写法。它不支持量词、不支持字符类、不支持分组。你把 ^\s*\r?\n 粘进扩展模式,它找的是这串字面字符,找不着。
正则模式(Regular expression):完整的 Boost 正则语法。字符类、量词、锚点、分组、反向引用、前后查找,全都在这一档。Notepad++ 从 v8.9.1 起用的是 Boost 1.90,语法源自 PCRE。
一张对照表,同一批需求在三种模式下的写法:
| 需求 | 普通模式 | 扩展模式 | 正则模式 |
|---|---|---|---|
把 abc 换成 def |
abc → def |
abc → def |
abc → def |
| 把所有换行换成逗号 | 做不到 | \n → , |
\r?\n → , |
| 删除所有空行 | 做不到 | 做不到 | ^[ \t]*\r?\n → 空 |
2026-08-29 改成 29/08/2026 |
做不到 | 做不到 | (\d{4})-(\d{2})-(\d{2}) → \3/\2/\1 |
| 删除行尾的连续空格 | 做不到 | 做不到 | [ \t]+$ → 空 |
| 找 3 到 5 位连续数字 | 做不到 | 做不到 | \d{3,5} |
"为什么我在正则模式敲 \n 没反应"——这个问题的标准答案是错的。 网上不少教程说"正则模式下 \n 是字面量 n",这是不对的,Boost 正则认 \n 转义。真正常见的原因是别的:Windows 文档的换行是 \r\n 两个字节,你只匹配并替换了 \n,\r 留在那儿,表现就是多出一堆空行或者 ^M 符号,看起来跟没替换一样。
所以两条实在建议:
- Windows 文档直接写
\r\n,别偷懒写\n。 - 如果你手上的文件来源杂(有 Windows 的也有 Linux 的),写
\R。它一次匹配\r\n、\n、\r三种,Notepad++ 7.9 之后完整支持。
两个官方行为,多数教程没提
这两条来自 Notepad++ 官方用户手册的 Searching 章节,属于"知道了能少挠半小时头"的类型:
- 选中正则模式后,「全字匹配」会被自动取消勾选并变灰。 手册原文是 Regular Expression 模式与 whole-word 不兼容。所以正则里要做全词匹配,得自己在模式两端加
\b,比如\bcat\b。指望那个复选框是没用的。 - 正则模式下「向上搜索」默认被禁用。 想在正则模式里从下往上找,需要去高级首选项里开
Allow regex backward search。不开的话,你点了"向上",它还是往下走。
. matches newline:最容易被忽略的开关
正则模式下面还有一个复选框,叫 . matches newline。默认不勾。
- 不勾:
\.匹配除换行以外的任意字符,所有量词都不会跨行。 - 勾上:
.连\r、\n一起吃,.*能一口气吞掉整个文件。
除了复选框,还能在查找串开头写修饰符:(?s) 等价于勾上,(?-s) 等价于不勾。写正则模板给别人用时,把 (?-s) 写在最前面比口头叮嘱"记得别勾那个框"靠谱。
绝大多数按行处理的正则(下面 15 个案例里的绝大多数)都要求这个框不勾。一旦勾了,^(.*)$ 匹配的就不是"一行"而是"整个文件",替换结果会离谱到你怀疑人生。
二、Ctrl+F 与 Ctrl+H:查找替换的基础盘
查找窗口里那几个复选框,每一个都对应一类"我明明写了、它就是没匹配上"的疑惑。
Ctrl+F 打开查找,Ctrl+H 直接切到替换标签。三个常用导航键:
F3找下一个,Shift+F3找上一个。Ctrl+F3:查找光标所在位置的那个词,不用手打。变量名很长的时候特别省事。
查找对话框里的几个选项:
| 选项 | 作用 | 什么时候勾 |
|---|---|---|
| 区分大小写 | 默认不区分 | 改代码里的标识符时必须勾上,否则 UserName 和 username 会被一起改掉 |
| 全字匹配 | 只匹配完整单词 | 正则模式下会灰掉,改用 \b |
| 环绕搜索 | 查到文件末尾自动回到开头 | 想从头到尾过一遍时勾 |
| 向上 / 向下 | 搜索方向 | 正则模式下"向上"默认不可用,见上一节 |
替换标签上有三个按钮,区别比你以为的重要:
- 替换:改当前这一处,然后跳到下一处。
- 全部替换:一次性改掉所有匹配,状态栏会告诉你替换了多少处。
- 在选定内容中替换:只有当你先在编辑区选中了一段文字时,这个选项才可用。它把替换范围锁死在选区里。
第三个按钮是安全网。处理大文件前,先用 Ctrl+G 跳到某个行号,用「编辑 → 开始/结束选择」框定一个区间,再替换,心里会踏实很多。这个功能的具体操作在 行号跳转与区间选择 里有配图说明。
还有个小习惯值得养:正式按"全部替换"之前,先点一次计数(查找标签上有这个按钮)。它会告诉你总共多少处匹配。你心里预期 30 处,它报 3000 处,那这条正则肯定写宽了,赶紧停下来看。
三、正则语法速查:够用就好的那 20 个
这一段是工具箱,不用背,用到回来查。Notepad++ 的正则能力很全,但日常 95% 的活只需要下面这些。
字符类
| 写法 | 含义 | 备注 |
|---|---|---|
. |
任意单个字符 | 不含换行,除非勾了 . matches newline |
\d |
数字 0-9 | |
\D |
非数字 | |
\w |
单词字符:字母、数字、下划线 | 中文不匹配 \w,这一点很关键 |
\s |
空白字符:空格、Tab、换行 | 会跨行匹配,用的时候留神 |
[a-z] |
范围内的任意一个字符 | |
[^0-9] |
方括号内 ^ 表示"非",即任意非数字字符 |
和行首锚点 ^ 是两回事 |
中文相关的坑:\w 不匹配汉字。想匹配中文字符,要么显式写 [\u4e00-\u9fa5],要么用 [^\x00-\xff] 表示双字节字符。我处理中文文本时更常用"反向排除"的思路,比如 [^,]+ 表示"任意个非逗号字符",比正面描述省心。
量词
| 写法 | 含义 |
|---|---|
* |
0 次或多次 |
+ |
1 次或多次 |
? |
0 次或 1 次 |
{n} |
恰好 n 次 |
{n,} |
至少 n 次 |
{n,m} |
n 到 m 次 |
贪婪和懒惰的差别,值得花三分钟搞懂。 量词默认是贪婪的,能吃多少吃多少;在量词后面加一个 ? 就变成懒惰,能吃多少算多少。
看这段文本:
名称(默认值)说明(单位)
| 查找串 | 匹配到什么 | 原因 |
|---|---|---|
(.*) |
(默认值)说明(单位) |
.* 贪婪,从第一个左括号一路吃到最后一个右括号 |
(.*?) |
(默认值) |
.*? 懒惰,碰到第一个右括号就停 |
大部分"我的正则多匹配了一堆东西"的事故,加一个 ? 就好了。
锚点
| 写法 | 含义 |
|---|---|
^ |
行首 |
$ |
行尾 |
\b |
单词边界 |
\B |
非单词边界 |
分组与反向引用
用 (...) 把一部分括起来,就成了一个捕获组,从左到右自动编号 1、2、3。替换串里用 \1、\2、\3 引用它们。
查找:(\d{4})-(\d{2})-(\d{2})
替换:\3/\2/\1
\1 就是第一个括号捕获到的内容。Notepad++ 用的是 Boost 正则引擎,替换串里的反向引用标准写法就是 \1 这种反斜杠加数字的形式。
需要"只分组不编号"的时候,写成 (?:...)。比如 (\w+)(?:\.(\w+))?,中间的 (?:...) 不占编号,后面的组还是 \2,不会因为插入了一个括号就全体错位。写复杂正则时这个习惯能救命。
转义
这些字符在正则里有特殊含义,想匹配它们本身就得在前面加反斜杠:
. ( ) [ ] { } \ | + * ? ^ $ -
容易漏的是 . 和 -。比如要匹配 IP 地址里的点,写 192.168.1.1 是不对的——. 会匹配任意字符,于是 192x168y1z1 也会被匹配上。正确写法是 192\.168\.1\.1。
换行符
| 写法 | 适用 |
|---|---|
\r\n |
Windows 文档 |
\n |
Unix / Linux / macOS 文档 |
\R |
通吃三种,Notepad++ 7.9+ 完整支持 |
\R 有个容易踩的细节:它不是字符类,不能放进方括号里。想匹配"Tab 或换行",写 [\t\R] 是错的,那会被理解成"Tab 或字母 R"。正确写法是 [\t\r\n] 或者 [\t\v]。这个坑官方文档专门标了出来,中文教程里基本没人提。
另一个 \R 的注意事项:个别情况下 UTF-8 with BOM 的文件会让 \R 失效。碰上了先转 UTF-8 无 BOM 再试,或者老实写 \r\n。
上面这些是日常够用的部分。想把正则用到更细(前后查找、条件匹配、Unicode 属性类),可以直接查 Boost 正则的 Perl 语法文档,那是 Notepad++ 这套引擎的源头规范。
四、15 个实战案例
这一段是全文的核心。每个案例统一给:场景、查找串、替换串、替换前文本、替换后文本、要点说明。四件套齐全,复制即用。
统一前提:搜索模式 = 正则表达式,. matches newline = 不勾选。风险等级按"改坏了多疼"标注。
清理类
案例 1:删除所有空行(含只有空格的空行)
场景:从网页或 Excel 复制出来的文本,混了一堆空行,还有看起来空、其实塞了空格和 Tab 的"假空行"。
查找串
^[ \t]*\r?\n
替换串
(什么都不填,留空)
替换前
订单号
客户名称
金额
备注
替换后
订单号
客户名称
金额
备注
要点:网上流传最广的版本是 ^\s*\r?\n,能用,但我不推荐。\s 包含换行符,是会跨行匹配的,遇到连续空行时它的回溯行为不太直观。写成 ^[ \t]* 就把匹配范围锁死在"行内的空格和 Tab",行为可预测。Unix 文档把 \r?\n 换成 \n 即可,或者直接用 \R。
如果只要删空行、不要动那些"假空行",把 * 改成 +:^[ \t]+\r?\n。
风险等级:低。Notepad++ 其实有内置的「编辑 → 行操作 → 移除空行(含空白字符行)」,纯删空行的话点菜单更快,不用写正则。
案例 2:删除行首和行尾的多余空格
场景:从不同来源粘贴来的数据,行首行尾带着肉眼看不见的空格,导致数据库导入时匹配不上。
① 行首空格
查找串
^[ \t]+
替换串
(留空)
② 行尾空格
查找串
[ \t]+$
替换串
(留空)
替换前
张三
李四
王五
替换后
张三
李四
王五
要点:两个查找串要分两次执行,不能合并成一条(正则里没有"或"能同时表达这两个位置且保留行内容)。顺序无所谓。
行尾空格有内置功能「编辑 → 行操作 → 移除尾随空格」,一键搞定,比正则快。行首空格没有对应的内置菜单,只能靠正则。这就是这类活的真实取舍:能点菜单就点菜单,点不到才写正则。
风险等级:低。但注意别在 Python 文件上跑行首清理,缩进是有意义的。
案例 3:把连续多个空行压缩成一个
场景:删完空行还想保留段落之间的分隔,不能全删光。
查找串
(\r?\n){3,}
替换串
\1\1
替换前
第一段
第二段
第三段
替换后
第一段
第二段
第三段
要点:这是全文我最喜欢的一条,因为 \1\1 这个写法有点巧。(\r?\n){3,} 匹配三个以上的连续换行,重复捕获组最终保留的是最后一次捕获的内容,也就是 \r\n 或 \n。所以 \1\1 会自动还原成原文档的行尾风格——Windows 文档出来还是 \r\n\r\n,Unix 文档出来还是 \n\n,不会被你顺手改成另一种格式。
替换串里我习惯老老实实写 \r?\n 相关的形式,不用 \R。\R 是"匹配任意换行"的简写,用在查找侧;替换侧你需要的是"插入一个确定的换行"。
风险等级:低。
案例 4:去掉所有换行,合并成一行
场景:把一列数据拼成 SQL 的 IN (...) 条件,或者拼成逗号分隔的字符串。
查找串
\r\n
替换串
,
替换前
1001
1002
1003
1004
替换后
1001,1002,1003,1004
要点:两个坑。
第一,先处理空行再合并。文档里如果有空行,\r\n\r\n 会变成两个逗号连在一起,得到 1001,,1002 这种结果。正确顺序是:先跑案例 1 删空行,或者先跑案例 3 压空行,再做合并。
第二,CSV 文件别这么干。格式正规的 CSV 里,引号内部是可以包含换行的(比如一个多行地址字段)。这种文件你按换行拆分,数据就散了。正则不理解嵌套结构,遇到带引号的 CSV,老实用 Python 的 csv 模块。
风险等级:中。合并是不可逆的视觉灾难,务必先另存。
案例 5:删除重复行
场景:几个来源的 IP 名单合并后要去重。
查找串
^(.*)(\R\1)+$
替换串
\1
替换前
192.168.1.10
192.168.1.10
192.168.1.20
10.0.0.5
10.0.0.5
替换后
192.168.1.10
192.168.1.20
10.0.0.5
要点:这条只能删"连续"的重复行,散落在文件各处的重复它管不了。想全局去重,得先排序:
Ctrl+A全选- 「编辑 → 行操作 → 升序排序行」
- 「编辑 → 行操作 → 删除连续重复行」
排序会把相同内容的行摞到一起,再去重就彻底了。代价是原顺序没了。所以:
- 顺序无所谓(名单、字典、配置值)→ 排序 + 删除连续重复行,一步到位。
- 顺序有意义(日志、时间序列)→ 用上面的正则,接受它可能漏掉非相邻的重复。
第三条路是装 Python Script 写五行代码,既能保序又能全局去重。这是正则的能力边界,绕不过去。
风险等级:中。排序会永久改变行顺序,动手前先另存。
格式转换类
案例 6:日期格式转换
场景:2026-08-29 批量改成 29/08/2026,或者任何字段换序的活。
查找串
(\d{4})-(\d{2})-(\d{2})
替换串
\3/\2/\1
替换前
2026-08-29
2026-09-01
2026-12-25
替换后
29/08/2026
01/09/2026
25/12/2026
要点:用 \d{2} 而不是 \d+,是为了限定位数,避免把 2026-8-9 或者更长的数字串也卷进来。写成 (\d+)-(\d+)-(\d+) 在简单文件上也能跑,但文件一杂就会误伤。
同一条思路可以套到 Oracle 的日期字面量上,把 '2026-08-29 10:30:00' 转成 TO_DATE 形式:
查找:'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})'
替换:TO_DATE('\1-\2-\3 \4:\5:\6', 'YYYY-MM-DD HH24:MI:SS')
六个捕获组,一一对应,不用手打。
风险等级:低。
案例 7:下划线命名与驼峰命名互转
场景:数据库字段 user_name 要改成 Java 属性 userName,或者反过来。
下划线转驼峰
查找串
_([a-zA-Z])
替换串
\U\1\E
替换前
user_name
order_create_time
id
替换后
userName
orderCreateTime
id
驼峰转下划线
查找串
([a-z])([A-Z])
替换串
\1_\L\2\E
替换前
userName
orderCreateTime
id
替换后
user_name
order_create_time
id
要点:\U 表示"从这里开始转大写",\L 是"转小写",\E 是"到此为止"。很多人只写 \U\1 也能出结果,但一旦替换串后面还有别的内容,没有 \E 就会把后面的东西一起转了,养成写 \E 的习惯比较稳。
下划线转驼峰这条对 _ 后面跟数字的情况不生效(比如 user_1),下划线会保留。这符合预期:user1 和 user_1 是两回事。
驼峰转下划线这条对连续大写会处理得不理想:HTTPRequest 会变成 HTTP_Request 而不是 http_request。缩写词的处理正则做不了,要么接受,要么上脚本。
风险等级:中。改标识符属于"改错了编译不过但查起来很痛苦"的类型,先试跑。
案例 8:全文大小写转换
场景:把一批常量名统一成大写,或者把一段全大写的英文转成正常大小写。
全部转大写
查找串
^(.*)$
替换串
\U\1\E
全部转小写
查找串
^(.*)$
替换串
\L\1\E
每个单词首字母大写
查找串
\b(\w)(\w*)\b
替换串
\U\1\E\2
替换前
hello world
NOTEPAD REGEX
zhang san
替换后(每个单词首字母大写)
Hello World
NOTEPAD REGEX
Zhang San
要点:. matches newline 必须不勾选,否则 ^(.*)$ 会把整个文件当成"一行",虽然转大写的结果碰巧一样,但转小写、首字母大写这类就会全乱。
最后一条对中文没作用,因为 \w 不匹配汉字,这是前面说过的。混排文本里中文部分会原样保留。
什么时候别用正则:只是改一小段选中文本时,内置的更省事。「编辑 → 转换大小写为」,快捷键是 Ctrl+U(转小写)、Ctrl+Shift+U(转大写)、Alt+U(每个词首字母大写)、Ctrl+Alt+U(句首字母大写)。正则适合全文批量,选中一小段的时候按两个键就完事了。
风险等级:中。注意别在 SQL 关键字、变量名上乱转。
案例 9:给每行加前缀、后缀、引号、逗号
场景:给一堆行统一加装饰,比如把纯文本变成 Markdown 列表、给配置项加注释符。
四种写法,按需要挑。
① 加前缀(行首)
查找串
^
替换串
-
② 加后缀(行尾)
查找串
$
替换串
,
③ 整行套引号(保留空行)
查找串
^(.+)$
替换串
'\1'
④ 整行套引号(连空行一起处理)
查找串
^(.*)$
替换串
'\1'
替换前
张三
李四
王五
替换后(用第 ③ 条 ^(.+)$ → '\1')
'张三'
'李四'
'王五'
替换后(用第 ④ 条 ^(.*)$ → '\1',注意空行变成了 '')
'张三'
'李四'
''
'王五'
要点:^(.*)$ 和 ^(.+)$ 只差一个字符,行为差很多。.* 允许零个字符,所以空行也会被匹配,结果空行变成 '';.+ 要求至少一个字符,空行直接跳过。要保留空行就用 .+,想连空行一起处理就用 .*。 这个区别在案例 10、14 里还会再遇到。
^ 和 $ 单独使用(不捕获任何东西)时,替换串里写什么就插入什么,这是最省事的加前缀后缀方式。
顺带一提:如果只是给连续多行加同样的前缀,列编辑更直观——Alt + 鼠标拖拽选中一块矩形区域,直接打字,所有行同时插入。插入递增序号则用 Alt+C 打开列编辑器。这两个功能的完整说明在 列编辑与列编辑器。列编辑要求各行位置对齐,正则不要求,各有所长。
风险等级:低。
案例 10:每行转成 SQL 的 VALUES 格式
场景:手上有一列用户名,要拼成 INSERT 语句的 values 部分。
查找串
^(.+)$
替换串
('\1'),
替换前
张三
李四
王五
替换后
('张三'),
('李四'),
('王五'),
要点:最后一行会多一个逗号,粘贴进 SQL 前手动删掉,或者在最后补一个 ('') 占位再删。我没有找到一条既优雅又可靠的正则能自动去掉末尾逗号,实践中手动删那一下更快。
这里用 .+ 而不是 .*,就是为了让空行不被转成 (''),——那会往数据库里插空记录。
如果你想一步到位连 INSERT 语句都生成,把替换串写成:
INSERT INTO t_user (name) VALUES ('\1');
风险等级:中。生成的是可执行 SQL,先在测试库跑。
提取与重组类
案例 11:从日志里提取 IP 地址
场景:Nginx 的 access.log 有几万行,只想要最前面那个客户端 IP。
查找串
^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*$
替换串
\1
替换前
192.168.1.23 - - [29/Aug/2026:10:12:33 +0800] "GET /api/user HTTP/1.1" 200 1024
10.0.0.7 - - [29/Aug/2026:10:12:34 +0800] "POST /api/login HTTP/1.1" 401 87
替换后
192.168.1.23
10.0.0.7
要点:思路是"捕获想要的,用 .*$ 吃掉不想要的"。本质不是替换,是删除。
\d{1,3} 不是严格合法的 IP 正则——它会匹配 999.999.999.999。严格版长这样:(?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d)。日常日志处理用简版够了,日志里的 IP 格式本来就是规范的。真要从杂乱文本里挑 IP,再用严格版。
风险等级:中。这会丢掉原文的全部其余内容,务必先另存。
案例 12:提取括号里的内容
场景:从"配置项(默认值)说明"这样的文本里,只要括号内的部分。
查找串
^.*?[((]([^))]+)[))].*$
替换串
\1
替换前
超时时间(30)秒
重试次数(3)次
编码格式(UTF-8)
替换后
30
3
UTF-8
要点:.*? 的问号是这条的关键。用懒惰匹配,它会停在第一个左括号;如果写成贪婪的 .*,它会一路找到最后一个左括号,一行里有两组括号时就取错了。
方括号里同时写了中文括号 () 和英文括号 (),因为中文文档里两种都常见。在字符集内部,这两个括号不需要转义。
风险等级:中。同样会丢弃括号外的内容,先备份。
案例 13:批量给建表语句加 DROP TABLE
场景:一份 SQL 脚本里有几十条 CREATE TABLE,要改成可重复执行的版本——每条前面先 DROP 一次。这是我开头说的那个 500 行脚本。
查找串
CREATE TABLE "(\w+)"
替换串
DROP TABLE IF EXISTS "\1";\r\nCREATE TABLE "\1"
替换前
CREATE TABLE "user_info" (
id INTEGER PRIMARY KEY,
name TEXT
);
CREATE TABLE "order_main" (
id INTEGER PRIMARY KEY
);
替换后
DROP TABLE IF EXISTS "user_info";
CREATE TABLE "user_info" (
id INTEGER PRIMARY KEY,
name TEXT
);
DROP TABLE IF EXISTS "order_main";
CREATE TABLE "order_main" (
id INTEGER PRIMARY KEY
);
要点:这条正则同时用了三个技巧:捕获组拿到表名、反向引用 \1 在替换串里用了两次、以及 \r\n 在替换串里插入一个真正的换行。Notepad++ 在正则模式下会解释替换串里的 \r 和 \n,所以你可以在一条替换里凭空造出新行。
如果你的表名不带引号,把查找串里的 " 去掉即可:CREATE TABLE (\w+)。表名里有下划线没问题,\w 包含下划线。
风险等级:高。
DROP TABLE是会删数据的语句。 生成完先通读一遍,确认表名都对上了,再拿到测试库执行。生产库上我个人的做法是只看不跑,让 DBA 过一遍。
案例 14:批量注释代码行
场景:临时把一段代码整段注掉做对比测试。
查找串
^(.+)$
替换串
// \1
替换前
function calc(a, b) {
return a + b;
}
替换后
// function calc(a, b) {
// return a + b;
// }
要点:用 .+ 的话空行会原样跳过(上面输出里第 3 行就是空着的)。如果你希望空行也加上 //,换成 .*,但那样会留下孤零零的 //,我个人觉得不如留空行清爽。
说实话,这个场景我更推荐用快捷键。 选中多行,按 Ctrl+Q 切换行注释,Ctrl+Shift+Q 是块注释。好处是注释符号会跟着当前语言自动变——JavaScript 是 //,Python 是 #,SQL 是 --,HTML 是 ``。你不用记每种语言用什么符号,它自己知道。
什么时候才需要正则?当你想给"所有包含某个词的行"加注释,Ctrl+Q 就做不到了,正则可以:查找 ^(.*TODO.*)$ 替换 // \1,只注释带 TODO 的行。
风险等级:低。
Ctrl+Q再按一次就取消了,还能撤销。
案例 15:交换等号两侧的内容
场景:配置文件写反了,要把 key=value 批量改成 value=key。
查找串
^([^=]+)=(.*)$
替换串
\2=\1
替换前
server_ip=192.168.1.10
max_retry=3
url=http://api.example.com?token=abc
替换后
192.168.1.10=server_ip
3=max_retry
http://api.example.com?token=abc=url
要点:第一组写 [^=]+ 而不是 .*,是为了处理"值里还有等号"的情况。看第三行:值是 http://api.example.com?token=abc,里面有个等号。如果两组都写 (.*),贪婪匹配会让第一组吃掉 url=http://api.example.com?token,只剩 abc 给第二组,结果就是错的。
[^=]+ 的意思是"一个或多个非等号字符",它撞上第一个等号就停,边界自然就对了。第二组用 .* 没关系,行尾就在那里。
这个"用排除字符集代替 .*"的思路,是写正则最实用的一招。 想匹配到某个分隔符为止,就把那个分隔符写进 [^...] 里,比调贪婪懒惰省事,也更不容易出错。
风险等级:中。
五、多文件批量替换(Ctrl+Shift+F)
改一个文件靠技巧,改 200 个文件靠纪律。后者出错的代价大得多,而且没有一键撤销。
Ctrl+Shift+F 打开「在文件中查找」,四个关键输入项:
| 输入项 | 填什么 | 例子 |
|---|---|---|
| 查找目录 | 目标文件夹的绝对路径 | D:\projects\api\src |
| 过滤器 | 文件名通配符,多个用分号隔开 | *.sql;*.log 或 *.* |
| 包含子目录 | 复选框,默认勾上 | 只想改当前层就取消 |
| 搜索模式 | 同样是三选一,选正则 |
填写目录时可以直接把文件夹从资源管理器拖进输入框,比手打路径快,也不会打错。
搜索结果会列在下方的面板里,按文件分组,双击任意一条就跳到那个文件的对应行。右键菜单里还有"复制全部匹配行",做汇总抽取时很好用。
在文件中替换的三条纪律
替换标签上有个「在文件中替换」按钮,点了之后,它会把当前目录下所有匹配的文件全部改掉,没有一个"逐个确认"的步骤。这跟单文件替换里"替换 vs 全部替换"的选择不一样,按下去就是全量。
所以我给自己定了三条,也建议你照做:
- 先搜索,不替换。 用「在当前文档中查找」不行,要用「在文件中查找」先跑一遍搜索,看结果面板底部报了多少个文件、多少处匹配。你预期 5 个文件,它报 50 个,停下来检查过滤器和正则。
- 备份整个目录。
Ctrl+Shift+F之前,先把目标文件夹复制一份。目录级替换的撤销不是Ctrl+Z能解决的——每个文件的撤销历史是独立的,你没法一口气撤销 200 个文件。 - 分批。 过滤器能分批就用分批:先跑
*.sql,确认无误再跑*.log。或者先用「包含子目录」不勾选,只改顶层,逐层推进。
另外两个提醒:
- 编码不统一会导致漏匹配。 一个目录里混着 GBK 和 UTF-8 的文件时,中文内容的搜索经常只对其中一部分生效,另一部分静悄悄地被跳过,你以为改完了其实没有。这种情况先处理编码问题,方法见 编码问题的处理方法。
- 目录里如果有 GB 级的日志,别直接上。 大文件的打开和替换行为跟小文件不一样,会卡,同上文那篇有专门的优化步骤。
性能提醒:处理成百上千个文件时,Notepad++ 官方中文版 页面提供的 64 位版本更稳。32 位程序在内存占用上去之后容易出现假死,你会分不清它是"在忙"还是"死了"。
标记与书签联动
「标记」标签页有个「标记所有」按钮,它会给所有匹配行加上行标记(彩色小圆点),同时可以勾选"书签行"把它们做成书签。然后 F2 / Shift+F2 在这些行之间跳。
在单个大文件里,这比"在文件中查找"好用得多:它能让你逐处过目,而不是一键改完。做手工复核时用这个。
六、宏:把一串操作录下来一键重放
这一段解决"我每天都要做同一套操作十几遍"的问题。
正则再强,它也是一次性的。你每次都得打开替换窗口、粘贴查找串、粘贴替换串、点按钮。如果这套动作一天要做二十次,就该录个宏了。
录制和播放
| 操作 | 菜单 / 快捷键 |
|---|---|
| 开始录制 | 「宏 → 开始录制」或 Ctrl+Shift+R |
| 停止录制 | 「宏 → 停止录制」或 Ctrl+Shift+R(同一个键) |
| 播放 | 「宏 → 播放」或 Ctrl+Shift+P |
| 保存 | 「宏 → 保存当前录制的宏」 |
| 绑定快捷键 | 「设置 → 快捷键映射器 → 宏」页签 |
录的时候有个细节:尽量用键盘,少用鼠标点具体位置。 宏记录的是光标移动和操作,你用鼠标点到第 37 行,它就记"移动到第 37 行";换个文件长度不一样,这一下就点空了。用 Ctrl+Home、Ctrl+End、方向键这类相对操作更稳。
保存之后给它起个名字,再到「设置 → 快捷键映射器 → 宏」页签里绑一个快捷键,以后一键触发。
宏存在哪
保存下来的宏写在 shortcuts.xml 里,跟你的自定义快捷键放在同一个文件。安装版的话路径是 %APPDATA%\Notepad++\shortcuts.xml,便携版在程序目录下。
这意味着两件事:
- 重装系统前记得把它拷出来。 宏录起来不难,但要你重新想一遍那套动作是什么,很烦。
- 它的备份方式跟其他配置文件一样。 具体哪些文件该备份、哪些不该跨版本拷贝,见 配置文件备份清单。
三个真实用例
- 批量加引号:光标定位到行首 →
Ctrl+右箭头跳到词尾 → 输入"→End→ 输入"→下箭头→Home。录一遍,之后一直播放到文件结束。 - 插入固定模板:把一段许可证声明、文件头注释录成一个宏,绑定
Alt+1,以后每个新文件按一下。 - 格式化粘贴来的数据:一整套"删行尾空格 → 删空行 → 每行加逗号"的操作串起来,一个宏搞定。
宏的边界
宏不会思考。它有三个硬限制,碰到就只能往脚本走:
- 不能条件判断。 它不理解"如果这行以
#开头就跳过"。 - 不能循环。 想让它"重复到文件结束",你得手动按住
Ctrl+Shift+P或者设置"播放多次",它自己不知道什么时候该停。 - 不能跨文件。 宏只在当前活动文档里跑。
最后一条最麻烦。正则有「在文件中替换」能覆盖一批文件,宏没有对应的批量入口。
七、脚本自动化:Python Script 与 NppExec
宏不会思考。凡是带判断、带循环、要跨文件的活,它都接不住,得交给脚本。
Python Script 插件
安装:「插件 → 插件管理」,搜 Python Script,装完重启。这是 Notepad++ 生态里最成熟的自动化插件,相关插件对比见 Python Script 插件。
装完之后你会得到两个核心对象:
editor:当前编辑区的文档对象。读文本、写文本、操作选区、获取行号,都靠它。notepad:应用级对象。打开文件、切换标签、弹消息框、操作菜单命令。
新建脚本:「插件 → Python Script → New Script」,存下来之后可以在「插件 → Python Script → Configuration」里把它挂到菜单上,甚至绑定快捷键。
三个可以直接抄的脚本:
一、在光标处插入当前时间戳
from time import strftime
editor.insertText(editor.getCurrentPos(), strftime('%Y-%m-%d %H:%M:%S'))
写日志、写变更记录的时候很方便。绑个 Alt+D,比手打日期快,也不会打错。
二、把当前文档的每一行套进模板
import re
lines = editor.getText().splitlines()
out = []
for ln in lines:
ln = ln.strip()
if not ln: # 空行跳过 —— 这种判断宏做不了
continue
out.append("INSERT INTO t_user (name) VALUES ('%s');" % ln)
editor.setText("\r\n".join(out))
注意那个 if not ln: continue,一个条件判断,宏就死在这儿。
三、对所有已打开的文件执行同一次替换
import re
pattern = re.compile(r'[ \t]+$') # 行尾空白
for (path, bufferID, index, view) in notepad.getFiles():
notepad.activateFile(path)
editor.setText(pattern.sub('', editor.getText()))
这个脚本遍历所有已打开的标签页,逐个清掉行尾空格。它不会自动保存,改完你还得自己 Ctrl+Shift+S 全部保存一遍。我故意没加自动保存——批量改文件这种事,留一道人工确认的关卡是值得的。
NppExec:调用外部命令
如果你只是想"写完直接跑一下",不需要操作编辑器内容,NppExec 更轻。
装好之后按 F5,输入:
NPP_SAVE
cd "$(CURRENT_DIRECTORY)"
python "$(FILE_NAME)"
保存成一个菜单项,绑定 F6,以后写完 Python 按一下就能看到输出。NPP_SAVE 是先保存,cd 切到文件所在目录,$(FILE_NAME) 和 $(CURRENT_DIRECTORY) 是 NppExec 的内置变量。
调试
脚本报错不会弹窗,默认静默失败。开控制台:「插件 → Python Script → Show Console」,语法错误和异常堆栈都打印在这里。写脚本时把控制台开着,能省很多瞎猜的时间。
脚本文件本身也存在磁盘上,通常在 %APPDATA%\Notepad++\plugins\Config\PythonScript\scripts\。要分享给同事、或者换电脑时带走,直接拷这个目录就行。
八、宏 vs 正则 vs 脚本:一张决策表
这一段解决"这个活到底该用哪个"。三个工具不是替代关系,是分工关系。
| 场景 | 正则替换 | 宏 | 脚本 |
|---|---|---|---|
| 一次性任务,规则明确 | 最合适 | 能干,但录制的功夫比敲正则还长 | 杀鸡用牛刀 |
| 同一套动作要重复几十次 | 每次都得手敲查找串 | 最合适,绑个快捷键一键搞定 | 也可以,但写代码更慢 |
| 需要条件判断(if / 循环) | 做不到 | 做不到 | 唯一选择 |
| 需要跨多个文件 | 「在文件中替换」能覆盖,但只能一次性全量 | 做不到,只在当前文档 | 最灵活,能遍历、能跳过 |
| 需要读写外部文件、调外部命令 | 做不到 | 做不到 | 唯一选择 |
| 改错了能回滚吗 | Ctrl+Z 一步回滚全部 |
Ctrl+Z 只能逐步回退 |
通常不可回滚,靠事前备份 |
一句话总结:一次性用正则,重复用宏,要判断就用脚本。 三者经常是接力关系:先用正则摸索出正确的替换规则,确认无误了再录成宏,等哪天发现"还得跳过某些行",就上脚本。
九、批量替换的安全操作纪律
这一段是全文最重要的部分,虽然它不讲技术。
先复制到新标签试跑
最简单可靠的办法,四下按键:
Ctrl+A全选Ctrl+C复制Ctrl+N新建Ctrl+V粘贴
然后在这个新标签里跑你的正则。改对了,把结果复制回原文件;改错了,关掉这个标签,Ctrl+W,原文件一根汗毛都没动。
只要文件不是特别大,这十几秒的开销绝对值得。
替换前的三秒检查清单
每次按"全部替换"之前,扫一眼这三件事:
- 搜索模式是不是「正则表达式」? 看替换窗口右下角的状态提示。这是第一号事故源。
- 命中数量对不对? 先点「计数」,跟你心里的预期对一下。差一个数量级就说明正则写宽了。
- 原文有备份吗? 至少
Ctrl+Shift+S另存一份.bak。目录级操作就复制整个文件夹。
第三条在「在文件中替换」上是硬性的,没有商量余地。
正则写了不生效?按顺序排查这 6 个
- 搜索模式选成「普通」或「扩展」了。 第一号原因,占比大概一半。
. matches newline勾了。 导致.*跨行,匹配范围比你以为的大得多。- 特殊字符没转义。
.、(、)、+、?这些,想匹配字面量就得加\。 - 换行符写错。 Windows 文档的换行是
\r\n,只写\n会留下孤立的\r。用\R最省心。 - 中文相关。
\w不匹配汉字,别指望它抓中文内容。 - 文件编码不统一。 GBK 和 UTF-8 混在一起时,中文搜索只对其中一部分生效,而且是静默跳过,没有报错。这种情况先去解决编码问题。
结语
回到开头那个 500 行的脚本。它最终用了八秒钟,但之前我花了大概十分钟试跑和调整:把 CREATE TABLE "(\w+)" 里的引号去掉试了一次,发现表名有不带引号的,又加了个问号让引号变成可选。写正则大部分时间不是花在"写"上,是花在"确认它对"上。
如果这 15 条里你只记得住一件,我希望是那个检查顺序:搜索模式对不对 → . matches newline 勾没勾 → 命中数量跟你预期差多少。三步走完再按"全部替换",基本不会出事。
下一步
- 想把这些操作固化下来、换电脑不丢设置 → 宏与快捷键的备份,里面有宏和快捷键的备份方式。
- 遇到批量处理大文件卡死、或者中文乱码 → 中文乱码与大文件排查。
Meta Title: Notepad++正则替换怎么弄?15个实例从入门到精通 Meta Description: 手工改500行日期要40分钟,一条正则只要8秒。本文先用对照表说清普通、扩展、正则三种搜索模式的区别,再给出15个真实替换实例,每个都配齐查找串、替换串、替换前、替换后四件套,可直接复制。含贪婪与懒惰、捕获组反向引用、多文件批量替换、宏录制与Python Script脚本入门,以及一套不毁文件的操作纪律。 Primary Keyword: notepad++ 正则替换 Secondary Keywords: notepad++ 正则表达式 替换, notepad++ 批量替换, notepad++ 正则 实例, notepad++ 正则 替换 换行, notepad++ 宏 录制 URL Slug: /search-replace.html Word Count: 9202 中文字(不含代码块)