news 2026/10/20 7:57:05

Notepad++正则批量给十六进制数加0x前缀的完整指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Notepad++正则批量给十六进制数加0x前缀的完整指南

第一次看到“在Notepad++里给十六进制数加0x前缀”这个问题时,我第一反应是“这还用问?查找替换嘛”。真正做的时候才发现,十六进制数的边界、0x重复前缀、纯数字的十六进制怎么处理,每个细节都能让你白改一堆文件。这是一个很典型的“正则批量改文本”场景,适用人群特别广:写单片机固件、看串口日志、整理内存数据、做CTF题,都会碰到。下面我把完整思路和实测过的正则写出来,照着抄就行。

1. 先想清楚:到底要把什么改成什么

1.1 数据的“身份”决定了正则怎么写

给十六进制数加0x前缀,看起来是“无脑加前缀”,但真正动手前要问自己三个问题:这些数字里是不是全是十六进制?有没有已经带0x前缀的?有没有普通英文单词混在中间?

我举个最常见的例子。串口日志里导出的数据是:

1A 2B 3C 4D 5E 6F 10 20 30

这里的1A、2B、3C明显是十六进制,但10、20、30到底是十六进制的0x10、0x20、0x30,还是十进制的10、20、30?如果不先确认这一点,正则一替换下去,该加的、不该加的全都加了,后面返工更痛苦。

所以在动手指之前,先给数据“定性”:所有数字串是否都来自十六进制采集设备,还是既有十进制又有十六进制的混合文本。我处理过的大部分场景是前者,串口打印、设备寄存器值、抓包数据,基本都是“见到数字全当十六进制看”。但一旦到了代码文件里,情况就复杂了,变量名、注释、字符串里都有可能混进看似十六进制的字符串,这时候就需要更严格的边界条件。

第一条经验:正则写得再好,也替代不了对数据格式的判断。先花一分钟确认数据来源,能省后面一小时。

1.2 批量处理的三种思路对比

除了手动一个一个改,常见思路有下面三种,我按实用性排个序:

第一种:Notepad++自带的查找替换 + 正则。这是最常用、也是性价比最高的方式,不需要装任何插件,只要查找框里写对正则,点一下“全部替换”就完成。适合纯文本、格式化日志、代码片段等绝大多数场景。缺点是正则本身有学习成本,边界条件写不对容易误伤。

第二种:TextFX、Python Script等插件脚本。适合要反复处理、或者替换逻辑比较复杂的情况。比如你每天都要把某个格式的数据加前缀,用脚本可以一键完成,还能顺带做大小写转换、排序、去重等操作。缺点是需要安装插件,而且新版Notepad++对某些插件支持得不太好。

第三种:用Excel、PowerShell等外部工具处理。如果数据只有一小段,复制到Excel用公式也能做,比如="0x" & A1。批量改几十个数字挺方便,但数据量大了、或者要直接在文件里改回原处,就绕远了。我一般只在数据是表格结构时才这么干。

1.3 为什么是Notepad++而不是其他编辑器

有人可能会说,VS Code、Sublime也都有正则替换,为什么非要守着Notepad++?这话没错,但Notepad++在某些场景确实有不可替代的方便:启动快、打开大日志不卡、对老机器友好,而且正则替换入口就在最顺手的“替换”按钮里,不用来回切面板。尤其是处理嵌入式开发里的日志文件时,我习惯先把文件拖进Notepad++,随手一个正则替换,比打开VS Code等插件加载快多了。

另一个理由是Notepad++的PCRE正则能力其实不弱。虽然不像专业编辑器那样支持所有高级语法,但咱们要用的“向后断言”“捕获分组”“非捕获分组”,它都能跑通。下面要讲的所有正则,我在Notepad++ 8.x上全部实测过,可以直接用。

2. 手把手:用Notepad++正则替换加0x前缀

2.1 最直接的写法:\b[0-9A-Fa-f]+\b

先看最直观的版本。按Ctrl + H打开替换窗口,在“查找内容”里填:

\b[0-9A-Fa-f]+\b

在“替换为”里填:

0x$0

然后勾选左下角的“正则表达式”,点“全部替换”。

这个正则的意思是:用单词边界\b圈住一段由十六进制字符(0-9、A-F、a-f)组成的连续字符串,$0代表整个匹配到的内容,替换时在前面加上0x。

比如文本:

1A 2B C3 4D

替换后得到:

0x1A 0x2B 0xC3 0x4D

这个版本简单粗暴,在纯十六进制数据里很好用。但它有两个明显的坑:第一,如果数据里已有0x1A这种带前缀的,0x里的0是十六进制字符,会被单独匹配出来,替换成0x0x1A;第二,像face、be、dead这种本身只由 A-F 组成的英文单词,也会被加上前缀。后面我会专门讲怎么避开这两个坑。

2.2 更稳妥的写法:用负向断言,避开已带0x的数

如果你面对的数据里既有已经带0x的,又有没带的,直接用上面的表达式会出大问题。举例:

0x1A 2B AB

用\b[0-9A-Fa-f]+\b匹配时,0x1A中的开头的0会被单独匹配到,因为它满足“单词边界 + 十六进制字符”,结果就变成0x0x1A 0x2B 0xAB,你还要再花一轮去修复0x0x。

更好的写法是把“可选前缀”也纳入匹配范围,确保重复替换也不会破坏已有前缀。查找内容用:

(?<![0-9A-Fa-fxX])(?:0[xX])?([0-9A-Fa-f]+)

替换为:

0x$1

这个正则拆开看是两部分:

  • (?<![0-9A-Fa-fxX]):负向后行断言,匹配位置前面不能是十六进制字符,也不能是x或X。这一下就把x1A、0x1A里的1A排除掉了,因为1A前面是x。
  • (?:0[xX])?:表示前面的0x或0X可有可无。如果本来带前缀,它会把前缀一起匹配进去;如果没带前缀,直接匹配数字部分。
  • ([0-9A-Fa-f]+):捕获真正的十六进制数字部分,替换成0x$1。

实际替换时,0x1A会被整体匹配,捕获组拿到1A,替换成0x1A,等于没变化;而2B没有前缀,捕获组拿到2B,替换成0x2B。重复执行多少次都不会出现0x0x。

这也说明了一个重要原则:替换时不是只匹配“要加前缀的数字”,而是把“已经是目标格式的内容”也包进来,统一通过捕获组重写,这样才安全。

2.3 只给“包含字母”的十六进制数加前缀

另一个让人头疼的场景,是数据里既有纯数字如10、20,又有含 A-F 的十六进制数如1A、C3。如果你只希望给含字母的十六进制数加0x,而纯数字保持原样,那就得在正则里加一个条件:匹配串里必须出现至少一个 A-F 字母。

查找内容写成:

(?<![0-9A-Fa-fxX])(?=[0-9A-Fa-f]*[A-Fa-f])[0-9A-Fa-f]+(?![0-9A-Fa-f])

替换为:

0x$0

关键在中间这个正向先行断言(?=[0-9A-Fa-f]*[A-Fa-f]):它要求当前位置往后看,存在“一串十六进制字符,其中至少有一个字母A-F”。这样一来,1A、C3、DEAD都会匹配;10、20、30因为全是数字,没有A-F字母,直接跳过。

我用这个表达式处理过一批日志,里面混着日期、计数器和寄存器值,效果很好。它默认“含字母的才是看起来像十六进制”,虽然不能100%保证语义正确,但在混合文本里比“见到数字全加前缀”安全得多。

2.4 按固定长度匹配:适配合法字节流

很多时候,十六进制数是有固定格式的,比如内存数据按字节显示时,每个数是两位:

1A 2B 03 C4 FF 10

这时候可以用{2}把长度限定死:

\b[0-9A-Fa-f]{2}\b

替换为:

0x$0

组合起来就能只匹配正好两位的十六进制数,不会把1A2B这种连续串当成一个数,也不会把A这种单字符扯进来。如果数据是四字节的,就换成{4};如果是长度在1到8位之间,就用{1,8}。

按长度匹配的最大好处是“所见即所得”,逻辑简单,误伤概率低。缺点是要求你对数据格式非常了解,如果源数据长度本身不固定,这个方案就不适用了。

3. 实操示例:三种常见数据格式的完整替换流程

3.1 空格分隔的日志字节流

这是最典型的场景。假设日志文件里是这样一行:

A1 B2 C3 D4 E5 F6 00 1F

目标是把每个字节都加上0x前缀,变成:

0xA1 0xB2 0xC3 0xD4 0xE5 0xF6 0x00 0x1F

步骤非常简单:

  1. Ctrl + H打开替换窗口。
  2. 查找内容填\b[0-9A-Fa-f]+\b,替换为填0x$0。
  3. 勾选“正则表达式”,点“全部替换”。

这里用最简的写法就够,因为整行数据都是十六进制字节,没有其余干扰项。替换完成后,建议再按一次Ctrl + H,把0x0x这种异常字符串搜一遍,确认没有重复前缀。

3.2 代码中的常量列表

如果是给C语言或Python代码里的一串宏定义加前缀,情况会稍微麻烦。比如:

#define A 1A #define B 2B #define C 10

你希望有没有字母都加前缀,让它们变成0x1A、0x2B、0x10,这时候最简正则依然有效:

  • 查找\b[0-9A-Fa-f]+\b
  • 替换0x$0

但要注意,代码里可能还有define、ALPHA这类变量名,ALPHA里的A虽然符合十六进制字符,但整个单词还有L、P这些不是十六进制字符的字母,所以\b[0-9A-Fa-f]+\b不会匹配ALPHA,这算是不幸中的万幸。真正的风险在于face、dead这种恰好全由A-F组成的单词。所以如果代码里有英文单词,强烈建议用第2.3节那个“必须包含A-F字母”的版本,并且结合上下文判断。

3.3 已经有一部分0x前缀,要补全缺失的

第三种情况很常见:文件里既有0x1A,又有裸的1A,需求是“不管带没带前缀,最终都要统一成0x”。直接用来最简正则会把0x1A里的0也匹配出来,变成0x0x1A。

所以要用第2.2节给出的“可选前缀 + 捕获组”方案:

  • 查找(?<![0-9A-Fa-fxX])(?:0[xX])?([0-9A-Fa-f]+)
  • 替换0x$1

我在替换前数了一下文件里的匹配次数,老实的1A和带前缀的0x1A都会被匹配,但替换后带前缀的保持不变,没带的全补上。这个方案在实际数据里非常稳,推荐保存到常用正则列表里。

3.4 替换前先“查找全部”做一次确认

不管用上面哪种正则,我强烈建议在点“全部替换”之前,先点一下旁边的“查找全部”。这一步能让你在搜索结果窗口里看到所有会被替换的内容和数量。

我自己的习惯是:先看匹配数量是不是和自己的预期一致。比如我肉眼数出日志里有50个地址,结果“查找全部”显示500个,那一定是正则过宽,把一堆不该匹配的字符串也圈进来了。这时候直接点“全部替换”,改坏文件再恢复就麻烦了。宁可多花十几秒检查,也不要闭眼替换。

4. 我踩过的坑,以及值得记下的排查技巧

4.1 为什么\b在连字符、下划线面前会“失灵”

很多人第一次用\b[0-9A-Fa-f]+\b时,会遇到一种情况:“1A-2B”这样的数据,只匹配出了1A和2B,看起来没问题;但换成“1A_2B”,有时候却整个1A_2B都不匹配了,或者只匹配出2B。

原因是\b表示的是“单词字符”和“非单词字符”之间的边界。下划线_属于单词字符,所以1A_2B中1A后面跟的是_,它和字母都是单词字符,之间没有边界,\b不会出现在1A和_这里,导致1A无法单独匹配。连字符-属于非单词字符,所以1A-2B可以正常匹配出两段。

如果你遇到类似下划线分隔的数据,不要硬用\b,而是要显式地用负向后行、负向前行把边界定义为“不是十六进制字符”。比如:

(?<![0-9A-Fa-f])[0-9A-Fa-f]+(?![0-9A-Fa-f])

这个写法不管前后是下划线、连字符、空格还是中文,只要不是十六进制字符,就能正常识别。这也是为什么前面我在高级写法里主要用断言而不是\b的原因。

4.2 “face”“be”这类英文单词也会被当成十六进制

十六进制字符集只有0-9A-Fa-f,这意味着大量英文单词天然就是合法十六进制数,比如face、be、dead、bad、cafe。如果文件是普通英文注释或字符串,你用\b[0-9A-Fa-f]+\b一替换,注释里的face会变成0xface,看着像乱改。

怎么避免?我常用的办法是加“必须有字母”的约束,也就是第2.3节那个正则,匹配串里至少要有一个 A-F。但这只能排除纯数字,无法排除face这种单词。要真正确认哪些是数据、哪些是文字,还得靠上下文。

实践中的妥协方案是:先确认文件类型。如果文件本身就是日志数据、代码常量、寄存器配置,里面很少出现完整的英文单词,那就可以放心用;如果文件是说明文档、带大量注释,那就要先用“查找全部”把匹配结果刷一遍,肉眼排除可疑项。

4.3 替换完出现0x0x,多半是“重复加前缀”

你自己手写正则的时候,如果只写[0-9A-Fa-f]+,不处理0x本身,很容易把0x1A里的0单独匹配出来,替换成0x0x1A。这种问题在日志里尤其隐蔽,因为0x1A本来就很像0x0x1A的子串,肉眼一扫未必能发现。

排查方法很简单:替换完成后,再开一次替换框,查找0x0x,如果搜到结果,说明重复加了。要修复,可以再执行一次:

  • 查找0x0x([0-9A-Fa-f]+)
  • 替换0x$1

不过这只是补救,更推荐的做法是一开始就用第2.2节那个“可选前缀”的正则,从根源上杜绝重复。

4.4 大小写混用怎么处理

十六进制数字的大小写影响搜索结果,1A和1a在语义上是同一个数,但在正则里它们是不同字符串。如果你的数据里既有大写又有小写,正则字符集要写成[0-9A-Fa-f]覆盖两种情况。

另外,替换后你可能会发现前缀0x是固定小写,但后面的1A可能变成1a(因为源数据本来就是小写)。如果希望统一格式:

  • 如果全部转大写:先复制一份备份,用菜单“编辑”→“格式转换”→“转为大写”处理整个文件。不过这会一并把注释、字符串里的大小写也改了,所以只适合数据文件。
  • 如果只想改十六进制部分:用Python Script插件脚本,在脚本里对捕获组做.upper(),这是更精细的做法,后面第5节给出代码。

我处理过的很多串口日志都是小写字母,而代码规范要求大写,遇到这种情况我一般直接用脚本一次性统一。

5. 进阶玩法:用Python Script插件做更灵活的批量处理

5.1 什么时候值得动用脚本

正则替换虽强,但遇到“不仅加前缀,还要统一大小写”“只处理选中区域”“根据前面某个字段决定要不要加前缀”这类需求时,表达式会变得又长又难维护。这时候我会切换到Python Script插件,写几行脚本,一劳永逸。

Python Script是Notepad++一个很老牌的插件,安装后能在“插件”菜单里看到Python Script入口。新版Notepad++的插件管理器不一定自带它,可能需要手动下载,如果装不上,也可以用NppExec等替代方案,但个人觉得Python Script最顺手。

如果只是临时一次性的替换,我建议还是用正则;如果是每天都要跑的固定流程,脚本的价值就体现出来了。比如我维护的一套日志清洗步骤,对选中区域执行脚本后,能一次性完成加前缀、转大写、去除重复值三步操作。

5.2 一段能用的Python脚本,以及关键点解释

下面这段脚本,是我存下来的“给十六进制数加0x前缀”最常用版本。它会对选中区域处理,如果没选中内容,则处理整个文档。

import re text = editor.get_sel_text() if not text: text = editor.get_text() pattern = re.compile(r'(?<![0-9A-Fa-fxX])(?:0[xX])?([0-9A-Fa-f]+)') def add_prefix(match): return '0x' + match.group(1).upper() new_text = pattern.sub(add_prefix, text) if editor.get_sel_text(): editor.replace_sel(new_text) else: editor.setText(new_text)

几个关键点说一下:

  • editor.get_sel_text()拿到当前选中的文本,没选中就返回空字符串。我用这个特性实现“有选区就只替换选区,没选区就处理全文”,防止手滑改掉整份文件。
  • 正则部分和刚才第2.2节完全一样,但替换函数里用了.upper(),会把十六进制部分统一成大写,比如1a变成0x1A。
  • pattern.sub会把所有匹配到的内容替换成add_prefix的返回值。

运行方法:打开Python Script的控制台,粘贴脚本运行;也可以先把脚本保存成.py文件,再通过菜单调用。我一般先在文档里选中一小段测试,确认结果无误后,再全选运行完整脚本。

5.3 把脚本变成菜单命令,一劳永逸

如果你和我一样要反复运行,可以把脚本注册成菜单命令。在Python Script里选择“Create Script”,给它起个名字,比如hex_add_prefix.py,然后把上面的代码保存进去。之后在插件菜单里就能直接点执行。

更妙的是,你还可以给它设快捷键:菜单“宏”→“管理快捷键”→“插件命令”,找到对应的脚本,指定一个组合键。我把它绑在Ctrl+Alt+H,现在处理日志基本就是“选中数据→按快捷键→完事”。整个流程快得像是编辑器原生功能。

用脚本处理后,建议再检查一下是否所有该加前缀的数字都变了。我习惯在脚本最后不直接setText,而是先在输出面板打印一条“共替换 xx 处”的消息,省得每次都心里没底。这个就留给你自己发挥吧。

我个人在实际操作中的体会是:正则替换这类事情,最怕的不是“不会写正则”,而是“没搞清楚数据格式就急着替换”。把文件类型、数字来源、是否已有前缀这三件事想清楚,再挑对应的正则,基本不会出错。最后再分享一个小习惯:每次替换前,先在查找框点一下“查找全部”,看看匹配数量和预期是否一致。如果差很多,千万别点“全部替换”,先回头把正则边界条件捋一遍。这个习惯帮我省下了无数次回滚的功夫,也希望你能用得上。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 7:56:40

给AI Agent造一个专属网站:用结构化事实层与Skills解决幻觉问题

1. 从"AI 又胡说八道了"说起&#xff1a;为什么我要给 Agent 造一个专属网站做 AI 应用开发这几年&#xff0c;最让我头疼的不是模型能力不够&#xff0c;而是它"太敢说"。你问它一个 API 的返回字段&#xff0c;它能一本正经地编出三个不存在的参数&#…

作者头像 李华
网站建设 2026/10/20 7:56:40

大模型面试必问RAG:核心原理、对比与实战避坑指南

最近在系统盘大模型应用方向的面经&#xff0c;发现一个绕不开的大头就是 RAG&#xff0c;检索增强生成。这个词几乎出现在每一场大模型相关面试里&#xff0c;不管是算法岗还是应用工程岗&#xff0c;面试官都喜欢从RAG切入&#xff0c;一路往下问。我本来以为原理听熟了就行&…

作者头像 李华
网站建设 2026/10/20 7:56:37

程序员转型AI系统设计避坑指南:从需求翻译到数据闭环的工程实践

1. 为什么程序员转型AI系统设计总踩坑1.1 从写业务代码到设计AI系统&#xff0c;中间隔着什么我带过不少从传统后端、前端转过来的同学&#xff0c;发现一个特别普遍的现象&#xff1a;大家学AI&#xff0c;第一反应是去啃Transformer原理、手推反向传播、把PyTorch的API背得滚…

作者头像 李华
网站建设 2026/10/20 7:56:16

CentOS 7实战:kubeadm搭建Kubernetes集群完整指南

搭 Kubernetes 集群这事儿&#xff0c;很多人一上来就想着去搞二进制部署、自己签证书&#xff0c;结果折腾两三天还没跑起来一个kubectl get nodes。其实在 CentOS 7 上&#xff0c;用 kubeadm 走一遍标准流程才是最稳的路径&#xff0c;尤其对于学习、测试、或者中小规模的生…

作者头像 李华
网站建设 2026/10/20 7:56:13

Arthas实战:Java线上问题排查与性能诊断利器

1. 为什么需要Arthas&#xff1a;线上问题排查的痛点1.1 传统排查方式为什么让人抓狂先聊一个让所有Java后端开发者都头疼的真实场景&#xff1a;线上服务突然CPU飙升、接口响应变慢、内存持续上涨&#xff0c;或者某个方法偶尔报出让人摸不着头脑的异常。这时候大家第一反应是…

作者头像 李华
网站建设 2026/10/20 7:55:42

零基础第一次参加黑客松:48小时参赛全流程与避坑指南

想写代码但还没写过完整项目&#xff0c;想在简历上留点东西却不知道从哪里下手&#xff0c;听说过黑客松又觉得自己水平不够——这种状态太常见了。去年我带着同样忐忑的心情参加了第一场黑客松&#xff0c;三天两夜下来&#xff0c;收获远超预期。那次的赛事恰好是联合了多所…

作者头像 李华