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 abcdef abcdef abcdef
把所有换行换成逗号 做不到 \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 章节,属于"知道了能少挠半小时头"的类型:

  1. 选中正则模式后,「全字匹配」会被自动取消勾选并变灰。 手册原文是 Regular Expression 模式与 whole-word 不兼容。所以正则里要做全词匹配,得自己在模式两端加 \b,比如 \bcat\b。指望那个复选框是没用的。
  2. 正则模式下「向上搜索」默认被禁用。 想在正则模式里从下往上找,需要去高级首选项里开 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:查找光标所在位置的那个词,不用手打。变量名很长的时候特别省事。

查找对话框里的几个选项:

选项 作用 什么时候勾
区分大小写 默认不区分 改代码里的标识符时必须勾上,否则 UserNameusername 会被一起改掉
全字匹配 只匹配完整单词 正则模式下会灰掉,改用 \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

要点这条只能删"连续"的重复行,散落在文件各处的重复它管不了。想全局去重,得先排序:

  1. Ctrl+A 全选
  2. 「编辑 → 行操作 → 升序排序行」
  3. 「编辑 → 行操作 → 删除连续重复行」

排序会把相同内容的行摞到一起,再去重就彻底了。代价是原顺序没了。所以:

  • 顺序无所谓(名单、字典、配置值)→ 排序 + 删除连续重复行,一步到位。
  • 顺序有意义(日志、时间序列)→ 用上面的正则,接受它可能漏掉非相邻的重复。

第三条路是装 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),下划线会保留。这符合预期:user1user_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 全部替换"的选择不一样,按下去就是全量。

所以我给自己定了三条,也建议你照做:

  1. 先搜索,不替换。 用「在当前文档中查找」不行,要用「在文件中查找」先跑一遍搜索,看结果面板底部报了多少个文件、多少处匹配。你预期 5 个文件,它报 50 个,停下来检查过滤器和正则。
  2. 备份整个目录。 Ctrl+Shift+F 之前,先把目标文件夹复制一份。目录级替换的撤销不是 Ctrl+Z 能解决的——每个文件的撤销历史是独立的,你没法一口气撤销 200 个文件。
  3. 分批。 过滤器能分批就用分批:先跑 *.sql,确认无误再跑 *.log。或者先用「包含子目录」不勾选,只改顶层,逐层推进。

另外两个提醒:

  • 编码不统一会导致漏匹配。 一个目录里混着 GBK 和 UTF-8 的文件时,中文内容的搜索经常只对其中一部分生效,另一部分静悄悄地被跳过,你以为改完了其实没有。这种情况先处理编码问题,方法见 编码问题的处理方法
  • 目录里如果有 GB 级的日志,别直接上。 大文件的打开和替换行为跟小文件不一样,会卡,同上文那篇有专门的优化步骤。

性能提醒:处理成百上千个文件时,Notepad++ 官方中文版 页面提供的 64 位版本更稳。32 位程序在内存占用上去之后容易出现假死,你会分不清它是"在忙"还是"死了"。

标记与书签联动

「标记」标签页有个「标记所有」按钮,它会给所有匹配行加上行标记(彩色小圆点),同时可以勾选"书签行"把它们做成书签。然后 F2 / Shift+F2 在这些行之间跳。

单个大文件里,这比"在文件中查找"好用得多:它能让你逐处过目,而不是一键改完。做手工复核时用这个。


六、宏:把一串操作录下来一键重放

这一段解决"我每天都要做同一套操作十几遍"的问题。

正则再强,它也是一次性的。你每次都得打开替换窗口、粘贴查找串、粘贴替换串、点按钮。如果这套动作一天要做二十次,就该录个宏了。

录制和播放

操作 菜单 / 快捷键
开始录制 「宏 → 开始录制」或 Ctrl+Shift+R
停止录制 「宏 → 停止录制」或 Ctrl+Shift+R(同一个键)
播放 「宏 → 播放」或 Ctrl+Shift+P
保存 「宏 → 保存当前录制的宏」
绑定快捷键 「设置 → 快捷键映射器 → 宏」页签

录的时候有个细节:尽量用键盘,少用鼠标点具体位置。 宏记录的是光标移动和操作,你用鼠标点到第 37 行,它就记"移动到第 37 行";换个文件长度不一样,这一下就点空了。用 Ctrl+HomeCtrl+End、方向键这类相对操作更稳。

保存之后给它起个名字,再到「设置 → 快捷键映射器 → 宏」页签里绑一个快捷键,以后一键触发。

宏存在哪

保存下来的宏写在 shortcuts.xml 里,跟你的自定义快捷键放在同一个文件。安装版的话路径是 %APPDATA%\Notepad++\shortcuts.xml,便携版在程序目录下。

这意味着两件事:

  • 重装系统前记得把它拷出来。 宏录起来不难,但要你重新想一遍那套动作是什么,很烦。
  • 它的备份方式跟其他配置文件一样。 具体哪些文件该备份、哪些不该跨版本拷贝,见 配置文件备份清单

三个真实用例

  1. 批量加引号:光标定位到行首 → Ctrl+右箭头 跳到词尾 → 输入 "End → 输入 "下箭头Home。录一遍,之后一直播放到文件结束。
  2. 插入固定模板:把一段许可证声明、文件头注释录成一个宏,绑定 Alt+1,以后每个新文件按一下。
  3. 格式化粘贴来的数据:一整套"删行尾空格 → 删空行 → 每行加逗号"的操作串起来,一个宏搞定。

宏的边界

宏不会思考。它有三个硬限制,碰到就只能往脚本走:

  • 不能条件判断。 它不理解"如果这行以 # 开头就跳过"。
  • 不能循环。 想让它"重复到文件结束",你得手动按住 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 只能逐步回退 通常不可回滚,靠事前备份

一句话总结:一次性用正则,重复用宏,要判断就用脚本。 三者经常是接力关系:先用正则摸索出正确的替换规则,确认无误了再录成宏,等哪天发现"还得跳过某些行",就上脚本。


九、批量替换的安全操作纪律

这一段是全文最重要的部分,虽然它不讲技术。

先复制到新标签试跑

最简单可靠的办法,四下按键:

  1. Ctrl+A 全选
  2. Ctrl+C 复制
  3. Ctrl+N 新建
  4. Ctrl+V 粘贴

然后在这个新标签里跑你的正则。改对了,把结果复制回原文件;改错了,关掉这个标签,Ctrl+W,原文件一根汗毛都没动。

只要文件不是特别大,这十几秒的开销绝对值得。

替换前的三秒检查清单

每次按"全部替换"之前,扫一眼这三件事:

  1. 搜索模式是不是「正则表达式」? 看替换窗口右下角的状态提示。这是第一号事故源。
  2. 命中数量对不对? 先点「计数」,跟你心里的预期对一下。差一个数量级就说明正则写宽了。
  3. 原文有备份吗? 至少 Ctrl+Shift+S 另存一份 .bak。目录级操作就复制整个文件夹。

第三条在「在文件中替换」上是硬性的,没有商量余地。

正则写了不生效?按顺序排查这 6 个

  1. 搜索模式选成「普通」或「扩展」了。 第一号原因,占比大概一半。
  2. . matches newline 勾了。 导致 .* 跨行,匹配范围比你以为的大得多。
  3. 特殊字符没转义。 .()+? 这些,想匹配字面量就得加 \
  4. 换行符写错。 Windows 文档的换行是 \r\n,只写 \n 会留下孤立的 \r。用 \R 最省心。
  5. 中文相关。 \w 不匹配汉字,别指望它抓中文内容。
  6. 文件编码不统一。 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 中文字(不含代码块)

还想看更多 Notepad++ 教程?

回到教程总入口,4 篇长文专题一次看全,从入门到进阶都不绕路。

查看全部使用教程
使用教程