首页/开发/正则与编码速查

正则与编码速查

正则语法与进阶技巧、各语言与工具差异、字符编码与 Unicode、Base64 与进制转换:开发通用速查。

共 200 条更新于 2026-10-17所属领域:开发
共 200 条

正则基础45 条

元字符、字符类、量词、分组与锚点

正则表达式的工作原理与匹配流程

正则匹配是「编译成程序、多起点尝试、失败回退」的过程:引擎默认从左到右返回第一个匹配,回溯型引擎最坏可达指数级复杂度,RE2 一类无回溯引擎保持线性。理解这套流程才能解释匹配结果与性能差异。

正则字面量与元字符的区别和用法

正则里字面量按原样比对,元字符代表重复、选择、分组、定位等操作。要匹配元字符本身需加反斜杠转义,且类内类外规则不同、POSIX 基本正则与扩展正则的转义要求相反,是模式静默失效的常见原因。

点号匹配任意字符的范围与陷阱

点号默认匹配除换行以外的任意一个字符,想跨界匹配换行要显式打开单行模式(Python 的 DOTALL、JS 的 s 标志)。它写在字符类内会退化为普通字符;与贪婪量词组合时是性能与误匹配的高发点。

字符类基础与中括号匹配规则

字符类用方括号表示「匹配其中任意一个字符」,恰好消耗一个字符;支持区间与取反写法,类内多数元字符退化为普通字符。右括号位置与区间端点是否包含是最容易出错的两处细节。

反向字符类与取反写法详解

取反字符类表示「不属于该集合的任意一个字符」,写法是左中括号后紧跟脱字符,恒消耗一个字符。与点号相反,它在多数引擎里默认包含换行,跨行分割时需显式排除换行符。

正则元字符转义规则与常见错误

转义用反斜杠把元字符变字面量、把普通字符升级为特殊序列。模式往往同时经过语言字符串、正则引擎与 shell 三层解析,未定义转义在 Python 3.7 起、PCRE 严格模式下会直接报错,是排查时首先要确认的层数问题。

星号与加号量词的匹配语义

星号表示重复零次或多次、加号表示一次或多次,两者都默认贪婪且作用于紧邻其前的单个元素。星号能匹配空串因而永远成功,是全局替换产生零长度命中的主因;加号校验更严格。

问号量词与可选匹配的写法

问号既是「出现零次或一次」的量词,也是把其他量词改成非贪婪的修饰符,写在左括号后则构成特殊分组前缀。同一符号的三种角色由所处位置决定,是模式可读性最容易被破坏的地方。

花括号量词的精确重复次数

花括号量词把重复次数写成固定值、闭区间或无上界三种形式,默认贪婪且只作用于紧邻其前的单个元素。写长度与定长校验时应配合全串锚定,想约束整组必须加圆括号。

量词默认贪婪行为及其影响

贪婪量词从最长的重复次数开始尝试,失败再逐步回退,结果是当前路径上最靠后的可行方案而非绝对最长。提取结果过长、跨界多数源于贪婪搭配了点号这类宽松字符。

行首行尾锚点的匹配语义

脱字符与美元符号是零宽的起始与结束锚点,默认只匹配整段文本的首尾,打开多行模式后对每行首尾都成立。它们是整串校验与逐行处理的关键,也常与字符类内的取反写法混淆。

多行模式下的锚点行为差异

多行模式只让起始与结束锚点对每一行生效,不影响点号的换行行为,也不影响量词贪婪策略;它与单行模式是两件独立的事,可同时开启。逐行提取与过滤是它的主要应用场景。

单词边界匹配与常见误用

单词边界是零宽断言,判断左右两侧是否跨越单词字符与非单词字符的分界;它是否成立取决于引擎对单词字符的定义,Python 处理文本时默认 Unicode 感知而 JavaScript 默认按 ASCII 处理,中文场景不宜依赖它做切分。

字符串开头结尾的锚定方法

绝对串首串尾锚点不受多行模式影响,常用来严格校验完整字段;行锚点在多数引擎里允许匹配末尾换行之前的位置,容易放过带换行的输入。跨引擎使用时严格程度并不统一,优先改用全串匹配接口。

捕获分组基础与括号分组规则

圆括号分组同时解决两件事:让量词作用于整组,以及把命中内容记录下来供提取与替换引用。第 1 组对应第一个左括号,未参与匹配与匹配空串含义不同,只看结构时应改用非捕获分组。

捕获组编号顺序规则详解

捕获组按左括号出现的先后顺序编号,第 0 组固定是整个匹配,嵌套时外层编号小于内层,非捕获分组不占编号而断言内的捕获括号通常占号。插入新括号会让后续组号整体后移,导致替换引用错位。

嵌套分组的捕获结果如何判读

嵌套分组中外层捕获范围包含内层,编号按左括号出现顺序由外向内分配,内层片段同时是外层内容的一部分。判读时先数括号定编号,再逐组核对起止区间,未参与匹配的组要按空值处理。

或分支匹配与分支顺序的影响

竖线表示择一,按从左到右顺序尝试、先成功者胜,不做最长优先。它的优先级很低,限定局部范围必须加圆括号;把更长的关键字写在前面对结果至关重要。

非捕获分组的用途与写法

非捕获分组用问号冒号开头的括号表示,只把元素聚成整体而不保存内容、不占用组编号,常用于对整组施加量词和限定分支范围。它仍会消耗字符,与零宽的断言不同,且在 POSIX 扩展正则中不被支持。

反向引用与重复内容匹配

反向引用在模式里引用前面捕获组实际匹配到的文本,实现「前后必须一致」的约束,例如成对引号与重复词检测。它是引擎扩展特性,RE2、Go 标准库不支持,且会让引擎失去线性优化。

分组重复匹配时捕获的是哪一次

捕获组位于重复量词内部时,每次迭代都会覆盖上一次,匹配结束只保留最后一次内容。需要全部迭代时应改为整体捕获后二次匹配、逐匹配遍历或先分割再处理,把内层组改成非捕获并不能解决覆盖问题。

空白字符类的匹配范围

空白类匹配空格、制表符、换行、回车等空白字符,取反写法匹配其余字符;它包含换行这一点是最常见的坑。行内处理应显式写成空格与制表符集合,严格校验时也不要依赖简写类。

数字与单词字符类的含义

数字类与单词类是最常用的预定义字符类:前者匹配一个数字字符,后者匹配字母、数字与下划线。它们的实际范围由引擎的字符语义决定,ASCII 与 Unicode 语义下结果不同,严格校验应改用显式区间。

简写字符类的隐藏陷阱

简写字符类的范围由引擎字符语义决定:数字与单词类在 Unicode 语义下会扩大,空白类包含换行,单词类还包含下划线,单词边界也随之变动。严格规则的场景应改用显式区间与显式集合。

自定义字符类与区间写法

自定义字符类的区间按字符编码顺序书写、两端包含,多个区间并列表示并集。大小写字母之间夹着符号,必须写两段区间;非拉丁文字不宜依赖编码区间,应改用字符属性类。

字符类内部元字符的处理

方括号内多数元字符退化为普通字符,只有反斜杠、位置敏感的脱字符与连字符、右中括号保持特殊作用;简写类仍然有效而量词不生效。退格字符与单词边界的写法混淆是类内最隐蔽的坑。

Unicode 字符属性类的写法

字符属性类按 Unicode 属性匹配字符类别或文字系统,比编码区间更可靠,适合多语言校验与汉字、标点识别。各引擎支持的属性名与生效前提不同,Python 标准库正则不支持,需按官方文档核对。

POSIX 字符类的含义与用法

POSIX 字符类用双层的冒号包裹写法在字符类内表示某一类别的字符,范围由 POSIX 标准与本地化设置共同决定。类名写错不会报错而是静默变成字面集合,跨环境复用时应固定本地化设置。

忽略大小写匹配的实现方式

忽略大小写开关让字符比较时按大小写折叠进行,影响字面量、字符类中的字母区间与字母简写类。多语言环境下折叠规则存在不对称情况,部分引擎还需额外开关才会按 Unicode 规则折叠。

点号匹配换行的模式开关

单行模式让点号把换行当作普通字符,从而支持跨行匹配,它只影响点号、不影响锚点,可与多行模式同时开启。名字容易误解为「只匹配一行」,开启后配合贪婪量词极易吞掉整段文本。

内联模式修饰符的作用范围

内联修饰符把忽略大小写、多行、点号跨行、自由间距等开关写进模式内部,使模式自包含;多数引擎按「从该处到所属分组结束」生效,可配合括号限定局部作用域。JavaScript 长期不支持模式内写法,需改用标志。

全串匹配与部分匹配的差别

部分匹配判断串中是否存在符合模式的一段,整串匹配要求整个输入完全符合,校验场景必须用后者。优先使用整串匹配接口,其次用绝对锚点,退而求其次才是比较匹配长度。

空字符串匹配产生的原因

允许零次重复的量词、零宽断言与空分支都能产生空匹配:它合法但不消耗字符,会让查找结果夹带空串、让替换插入多余内容,自写遍历时不推进位置还会死循环。改用至少一次的量词或过滤空结果即可规避。

空分支与可选分支的匹配后果

竖线一侧留空构成空分支,它匹配空串,等价于把该部分写成可选;代价是引入空匹配,与量词组合时还可能造成零宽重复。用问号量词替代空分支语义相同且更清晰,跨工具使用前需验证兼容性。

字符串与正则双层转义的坑

正则模式通常要经过字符串字面量与正则引擎两层解析,写进配置或命令行还会多一层。少一层会让转义失效、多一层会变成匹配反斜杠本身,解决之道是优先使用原始字符串写法并打印最终模式核对。

原始字符串写正则的必要性

原始字符串让语言层不再解释反斜杠,把两层解析压回一层,是书写正则的推荐写法。它只影响字符串层、不影响正则层转义,也无法表示以奇数个反斜杠结尾的内容,配置文件通常不支持该语法。

自由间距模式下写可读正则

自由间距模式忽略模式中的空白并把井号到行尾视为注释,适合排版与维护长模式;字符类内部的空白与井号仍是普通字符,匹配空格需要转义写法。标准 JavaScript 正则不支持该标志。

复杂正则的拆解与可读性

复杂正则应按代码对待:用自由间距分段、用命名分组取代数字编号、用注释与样例留下意图,并把可复用片段抽成常量。任何可读性改造都要用同一批正例与反例验证行为不变。

逐字符调试正则的定位方法

调试正则的要点是逐段验证与先排除环境问题:先确认最终模式字符串、匹配语义与开关来源,再用非捕获分组切块、逐段追加验证,结合位置信息定位偏差。每次只改一处并保留最小复现样本。

正则语法结构的可视化方法

可视化把正则解析成流程图或结构树,用于确认分组边界、量词作用范围与优先级;部分语言标准库提供内置解析接口可直接打印结构。它反映语法结构而非运行过程,语义细节仍需在目标引擎上实测。

正则上线前的测试用例设计

正则上线前应准备覆盖正例、反例与边界的样本集,反例按加多余内容、缺内容、换非法内容三类构造最能暴露宽松判定;还需覆盖全角字符、不可见空白、换行风格与超长输入,样本预期应与业务规则对齐。

常用元字符总览与含义对照

常用元字符分四类:锚点定位、字符类描述单字符、量词控制重复、分组与分支组织结构,另有反斜杠负责转义。同一符号在方括号内外可能含义不同,扩展构造的支持范围随引擎而异。

方括号与圆括号的功能区别

方括号定义字符集合、匹配其中一个字符且恰好消耗一个字符,圆括号定义分组、把若干字符作为一个整体并可选捕获内容。量词跟在方括号后重复单字符位置,跟在圆括号后重复整组,混用会让模式语义完全走样。

竖线运算符的优先级规则

正则的优先级是分组高于量词、量词高于连接、连接高于分支,竖线优先级最低且会吞到最近的括号边界。分支不被括号包住时锚点只覆盖其中一支,是校验被绕过的常见原因,建议显式加括号。

锚点与量词的组合匹配行为

锚点与断言都是零宽元素,对它们加量词只是要求零宽条件重复成立,语法多被允许但语义有限、实现存在差异。多数看似「锚点带量词」的写法其实作用于后面的字符类,判断依据是量词紧邻的前一个元素。

正则进阶45 条

贪婪与懒惰、回溯优化、环视、常用校验实例

贪婪与懒惰量词的匹配差别

贪婪量词从最长开始尝试并逐步回退,懒惰量词在量词后加问号,从最短开始并逐步加长;多终点场景下贪婪取靠后的匹配,懒惰取靠前的匹配。性能上懒惰通常回退更少但并非保证,边界明确时用精确字符类更稳。

懒惰量词的典型使用场景

懒惰量词适用于「在最近定界符处停下」的提取需求,例如不嵌套的标签对、引号字段与两标记之间的片段。目标内容内部含同类定界符或存在嵌套时它不再可靠,应改用精确字符类、断言或解析器。

占有量词与原子组的匹配优势

占有量词与原子组都表示「匹配成功后放弃回退」,能显著抑制无效回退,但可能改变模式接受的结果集合。PCRE、Java、Python 3.11 起支持,.NET 支持原子组,JavaScript 与 RE2 类引擎不支持。

正则回溯的工作流程解析

回溯型引擎按深度优先尝试,把量词长度、分支选项等备选压入选择栈,失败时弹出换路;相邻不定长重复会让选择点相乘,嵌套重复更是指数增长,这就是正则性能问题的根源。缩窄可匹配范围是降低回退规模最有效的手段。

灾难性回溯的成因与识别

灾难性回溯由重叠或嵌套的不定长重复加上整体匹配失败造成,耗时随输入长度呈指数增长,属于可被恶意构造的拒绝服务风险。缓解手段是重构掉重叠选择点、限制输入长度、设置匹配超时,必要时改用无回溯引擎。

嵌套量词导致的性能崩溃

嵌套量词让同一段内容有多种拆分方式,选择点随长度指数增长,输入匹配失败时全部方案都要尝试,是灾难性回溯的典型来源。多数嵌套重复在语义上冗余,删除外层或改用精确字符类即可消除风险。

正则性能优化的常用手段

正则性能优化应先测量耗时曲线,再按三层推进:减少工作量(字面查找、锚定、固定前缀)、减少选择点(收窄字符类、消除嵌套重复、原子组)、工程兜底(长度上限、匹配超时、预编译复用、无回溯引擎)。

原子分组如何阻止无效回溯

原子组在内部匹配成功后丢弃内部回溯点,使该段内容不再参与回退,用于抑制回退爆炸或表达「一旦确定不再改变」的语义。它会消耗字符但不捕获,且可能改变匹配结果,JavaScript 不支持。

正向先行断言的基础写法

正向先行断言检查右侧是否满足某条件,零宽不消耗字符,被检查内容不出现在结果里,多个断言并排即构成「与」关系,常用于密码复杂度与格式多重约束。其内部子模式同样参与尝试,写得太宽会带来回退压力。

负向先行断言的排除匹配

负向先行断言要求右侧不满足某条件,零宽不消耗字符,用来排除整段结构(单字符排除用取反字符类更合适)。常与行首锚点组合过滤注释行,判断整串时需让断言覆盖整个输入范围。

后行断言的基础用法与限制

后行断言检查当前位置左侧是否满足条件,零宽不消耗字符,用于提取符号之后的内容并让符号保留在结果之外。多数实现要求断言内部固定宽度,变长支持随引擎与版本而异,方向写反是最常见错误。

变长后行断言的引擎支持差异

后行断言需要引擎知道往回看多少字符,所以多数实现要求固定宽度;变长支持随引擎与版本而异且常设上限。跨引擎复用时应优先固定宽度,或改用捕获分组加后处理、先行断言改写与分两步匹配。

零宽断言不消耗字符的含义

零宽断言只判断当前位置是否满足条件,不消耗字符也不进入匹配结果,因此可以并排叠加形成「与」关系,也能作为替换的插入点。它与锚点同属零宽结构,可能产生空匹配,需要留意替换结果。

断言与捕获分组的取舍

断言回答位置是否满足条件且零宽不进入结果,捕获分组负责把内容取出来;需要同时满足时可用断言加捕获组合,或改用捕获前缀加后处理的方案以提升兼容性。断言内部的捕获可能占用组编号,容易造成取值错位。

命名分组的写法与引用方式

命名分组按名字而非编号读取捕获内容,模式调整时引用不易错位;定义语法分「问号大写 P 加尖括号」与「问号加尖括号」两派,模式内引用与替换引用也各有写法,跨引擎复用需逐一核对。

命名分组的反向引用写法

命名反向引用用 \k<name> 或 (?P=name) 在同一条正则里再次引用某个命名分组匹配到的文本,用来强制配对(引号、标签、重复词)。各引擎写法不同,Python re 只支持 (?P=name),写错会直接编译失败。

按名称提取分组结果的写法

按名字取分组结果让取值代码与模式解耦:Python 用 group('name')/groupdict(),JS 用 groups.name,PHP 用 $m['name'],Java 用 group("name")。要特别注意组未参与匹配时的返回值差异(None/null/undefined/空串),它决定了后续判空与类型转换逻辑。

捕获结果转字典的处理方法

把捕获结果转成字典是正则接入业务前的标准动作:Python 用 groupdict() 一步到位,其他语言用组名与 groups() 手动配对。关键在于过滤未参与组、区分空串与缺失、并把类型转换集中在这一层完成。

条件匹配的语法与适用场景

条件匹配写成 (?(组号或组名)yes|no),按前面某个组是否参与匹配来选分支,适合处理「可选前缀决定后续格式」的场景。PCRE、Perl、.NET 支持完整语法,Python re 只支持按组号或组名,断言条件与 Java 均不支持。

条件分支的替代方案对比

条件匹配并非必需:交替分支、可选组加断言、拆多条模式、分支重置组、代码侧分支都能实现同样效果。选择依据是引擎支持面、可读性与排查成本,形态超过两三种时通常代码侧分支最稳妥。

递归子模式与嵌套结构匹配

递归子模式用 (?R)、(?1) 或 (?&name) 让模式调用自身,用来匹配层数不定的嵌套结构,例如配对括号与嵌套占位符。它是回溯引擎特有语法,PCRE、Perl、Oniguruma 与 Python regex 库可用,Python re、Java、.NET 不支持。

平衡组匹配配对括号的思路

平衡组是 .NET 特有的配平手段:用 (?<组名>…) 入栈、(?<-组名>…) 出栈,再用 (?(组名)(?!)) 断言栈空,可校验括号与标签是否成对。其他引擎没有该语法,PCRE 系通常改用递归子模式。

分支重置分组的作用范围

分支重置分组 (?|…) 让交替的每个分支从同一序号重新编号,使不同格式里的同位置字段共用组号,简化取值逻辑。PCRE/PHP、Perl 5.10 起、Java 7 起与 Boost 支持,Python re 与 JS 不支持。

重置匹配起点的写法与用途

\K 是 PCRE、Perl、Ruby 等引擎的「重置匹配起点」记号:其左侧内容照常参与匹配但不进入最终结果,常用于只取键值后面的片段。Python re、JS、Java、.NET、Go 不支持,需改用捕获组或后行断言。

回溯控制与超时保护策略

回溯控制的核心是消除嵌套量词与重叠可选项,再用原子组、占有量词、互斥字符类把回溯量压到线性水平,并配合输入长度限制与引擎限额(PHP 的 pcre.backtrack_limit、.NET 的匹配超时等)。调大限额不是解决办法。

正则执行超时与熔断保护

正则超时保护按平台选手段:.NET 用 Regex 超时参数、Python regex 库有 timeout、PCRE 系靠 match limit,Java 与 Node.js 需要线程或 worker 隔离,并配合输入长度上限与熔断降级。线程超时不会真正停止仍在运行的计算,必须叠加并发限制。

PCRE 与 POSIX 正则语法差异

POSIX 与 PCRE 的差异集中在字符类写法、简写类、非贪婪量词、环视与匹配语义:POSIX 用 [[:digit:]] 且规范要求最左最长匹配,PCRE 用 \d 等简写类并支持环视、非贪婪与命名组。可移植脚本优先 POSIX 写法,应用代码通常用 PCRE。

基础正则与扩展正则的差异

BRE 与 ERE 的核心差异是转义方向:BRE 里分组、量词、交替需要转义(\( \)、\{ \}、\|),ERE 里这些字符默认就是元字符、字面值才需转义。grep 与 sed 默认 BRE(-E 切 ERE),awk 默认 ERE。

主流正则引擎特性对照思路

做正则选型先分清两类引擎:回溯式(PCRE、Python re、Java、JS、.NET)功能齐全但可能指数级回溯,线性时间引擎(RE2、Go regexp、Rust regex)安全但语法是子集。对照时按语法特性、Unicode 处理、失败语义、限额能力四个维度核对,并锁定具体版本。

各引擎 Unicode 支持差异

Unicode 支持差异集中在三点:字符串按字节还是码点处理、\w 等简写类是否覆盖非 ASCII、大小写折叠规则。Python str 与 .NET 默认包含非 ASCII 字母,JS 与 Java 默认只认 ASCII,PHP 需要显式写 \p{...},Go regexp 简写类也是 ASCII 语义。

正则引擎性能对比的测试方法

正则引擎性能对比的要点是样本与统计:必须同时覆盖成功、失败与最坏情况输入,把编译与匹配分开计时,并报告分位数与长度-耗时曲线。平均值和单轮运行会掩盖长尾,冷启动与稳态表现也要分开记录。

邮箱格式校验正则的边界问题

邮箱校验应当分层:用一条宽松正则粗筛字符集与基本形状,长度限制(本地 64、整体 254)与真实可用性分别交给代码判断和确认邮件。照搬 RFC 完整语法既不现实也易触发回溯风险,过严的规则还会误杀含加号、点号的合法地址。

IPv4 地址校验正则与取值范围

IPv4 校验正则需要按数值区间逐段表达,推荐 25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d 并整串锚定,避免 \d{1,3} 放过 256 这类越界值。形状校验之外,私有段、环回与前导零等语义问题应交给地址库或输入规范处理。

IPv6 地址校验正则的简化思路

IPv6 校验不建议写巨型正则,而应分步做:先剥离区域标识与前缀长度,再判断双冒号出现次数与两侧组数,最后交给地址库做权威校验。判断要点是八组上限、双冒号最多一次、每段 1 到 4 位十六进制。

URL 解析正则的拆分与校验

URL 解析正则适合把协议、主机、端口、路径、查询串、片段切开,或从混杂文本里抽取链接;整体合法性校验应交给语言内置的 URL 解析器。主机部分要排除冒号与斜杠,路径不能用贪婪匹配,否则查询串与片段会被吞进去。

域名格式校验正则的编写

域名校验规则是总长不超过 253、每标签 1 到 63 字符且不以连字符开头结尾、至少两个标签。实现时先剥离末尾点并统一小写,按用途区分是否允许单标签与下划线;非 ASCII 域名应按 punycode 形式处理。

日志行字段提取正则的设计

日志字段提取的关键是先采样确认格式再写模式:引号包裹字段用排除引号的字符类,方括号内用排除右方括号的字符类,空值(常见为单个连字符)单独判断。不匹配的行必须计数留样,结构化日志应直接交给 JSON 解析器。

身份证号校验正则与校验位

18 位身份证号由地址码、出生日期、顺序码与校验位组成,正则只能校验形状(含月份与日期的粗范围),日期真实性与末位校验位必须用代码计算,校验位按模 11 减 2 的加权算法得出。校验位自洽不代表号码真实存在。

手机号校验正则的宽严取舍

手机号校验宜宽不宜严:常用写法是限制 11 位与首位数字范围,并允许加号国家码与常见分隔符,输入先归一化再校验;E.164 用于国际场景。归属地、运营商与是否在用无法靠正则判断,需要专门号码库。

日期时间格式校验正则写法

日期时间正则的作用是把月、日、时、分、秒限制在各自的数字范围内,并固定整体格式;大小月天数、闰年、时区有效性必须交给日期库判断。跨时区比较前要统一换算,否则排序与聚合都会出错。

密码强度校验正则的组合思路

密码强度校验用零宽前瞻组合表达「各类字符至少一个」,长度限制放在末段字符集上,顺序无关是前瞻的天然优势。正则只能判断字符类别是否存在,无法判断是否好猜,长度上限与哈希算法输入限制必须另行处理。

用正则提取 HTML 标签的局限

HTML 嵌套、属性含大于号、脚本块伪标签等特点使正则无法可靠解析网页,正则只适合结构已知的规整片段。真实场景应使用 html5lib、BeautifulSoup、lxml、DOMParser 等解析器,先移除脚本与样式再取文本,并对输入长度设限。

正则提取 JSON 字段的风险

用正则提取 JSON 字段在真实数据上不可靠:字符串内的转义引号会让非贪婪匹配提前截断,嵌套同名字段也会造成重复命中。可靠做法是用 JSON 解析器或 jq 按行解析,正则只用于定位片段或对自产出格式做粗筛。

中文字符匹配正则的编码前提

匹配汉字前先确认编码与引擎能力:推荐按 Unicode 脚本属性匹配(JS 写完整脚本名并带 u 标志,PHP 带 /u,Java 用 IsHan),Python 标准库需手写区间或改用第三方库。基本区区间不覆盖扩展区生僻字,中文标点与中文数字〇也不属于汉字脚本。

语义化版本号校验正则写法

语义化版本校验应采用规范给出的正则:三段数字不允许前导零,预发布标识用连字符引导且数字段同样禁止前导零,构建元数据用加号引导且不参与比较。版本大小比较必须用专门库,字符串比较会给出错误结论。

各路工具里的正则35 条

Python / JS / PHP / grep / MySQL / ES 差异

Python re 模块常用接口梳理

Python 标准库 re 的常用接口是 compile、search、match、fullmatch、findall、finditer、sub、subn、split、escape,模块级函数与预编译对象功能等价并共用缓存。预编译的价值在复用与集中管理,模式非法时在编译阶段抛 re.error。

Python 匹配与搜索接口差异

Python 三个接口的差别在起点与终点:match 从串首开始但不要求匹配到末尾,search 扫描任意位置,fullmatch 要求整串匹配。校验用 fullmatch,提取用 search,多行模式下还需区分行首锚点与串首锚点。

Python 分组结果的读取方法

Python 匹配对象通过 group、groups、groupdict、span、expand 读取分组结果:序号从 1 开始,0 是整段匹配,未参与的组返回空值而非空串。命名组同样占用序号,统一按名字取值可避免序号漂移带来的静默错误。

Python 正则替换与回调函数

Python 的替换接口用模板字符串或回调函数决定替换内容:模板支持序号与命名组引用,回调接收匹配对象并返回字符串,适合条件判断场景。subn 与 sub 的区别在于是否返回替换次数,模板一律建议使用原始字符串以免转义混淆。

Python 正则预编译与缓存机制

Python 模块级正则函数内部共用一套编译缓存,因此预编译的主要价值是让编译错误提前暴露、在热点路径复用对象与集中管理标志位。缓存容量属于实现细节,大量动态模式会挤占缓存,关键模式应显式预编译并长期持有。

Python 正则标志位的作用

Python 正则标志位控制匹配语义:IGNORECASE 忽略大小写,MULTILINE 让锚点按行生效,DOTALL 让点号匹配换行,VERBOSE 便于书写长模式,ASCII 让简写类退回 ASCII 语义。全局内联标志必须位于模式开头,局部标志用带冒号的形式限定在分组内。

Python 详细模式写可读正则

Python 可读模式(VERBOSE)忽略模式中未转义的空白与井号注释,便于把长模式分行书写并逐段加注释。字符类内部的空白不被忽略,匹配真实空格必须转义;字符串拼接时要注意注释会延伸吞掉后续片段。

Python regex 库的增强特性

第三方 regex 库在保持接口兼容的同时补上了标准库缺失的能力:Unicode 属性转义、递归、变长后行断言、重置匹配起点、超时参数,以及重叠匹配、部分匹配与模糊匹配。引入前需权衡依赖成本,超时参数不能替代模式优化。

Python 两套正则库的选型

Python 正则选型的默认答案是标准库 re:零依赖、随运行时获得修复、覆盖多数场景。只有确实需要 Unicode 属性、递归、变长后行断言、超时或重叠与模糊匹配时才引入第三方 regex 库,并把使用范围收口在少数模块内,迁移时以样本回归为准。

JS 正则字面量与构造器差异

JS 正则的字面量在解析期确定、反斜杠写一个、不能插入变量;构造器在运行时求值、字符串里反斜杠要写两个、适合动态模式但必须自行转义元字符。构造器复制已有正则时不继承状态,非法模式会在调用时抛错。

JS 正则标志位与粘性匹配

JS 正则标志位分工明确:全局标志决定是否查找全部并维护状态,粘性标志要求从当前位置精确匹配,多行与点号匹配换行影响语义,Unicode 模式按码点处理并启用属性转义,区间标志提供下标。带状态的对象被共享时最易出现漏匹配。

JS 匹配接口返回结果差异

JS 各匹配接口返回结构不同:字符串匹配方法无全局标志时返回含分组的详情对象,有全局标志时只返回整体匹配数组;正则执行方法始终返回详情对象但在全局或粘性标志下带状态;迭代接口兼顾分组与批量遍历,但要求全局标志。

JS 全局正则的 lastIndex 陷阱

JS 正则启用全局或粘性标志后会记录上次匹配位置,下一次从该位置继续,失败时复位,因此共享同一对象做纯判断会出现结果翻转。规避方式是按用途区分:判断用无状态模式,批量遍历用迭代接口,必须复用时显式复位位置。

JS 字符串替换中的正则用法

JS 替换接口支持模板与回调两种替换值:模板用美元符号引用整体匹配、前后文本与分组,回调按固定顺序接收匹配、分组、位置、原串与命名分组对象。默认只替换第一处,全量替换需要全局标志,全量替换接口传入非全局正则会抛错。

JS 后行断言的兼容性处理

JS 后行断言在较新语言版本中纳入标准,老环境不支持时字面量形式会导致解析阶段报错、整段脚本失败。处理方式是运行时用构造器做能力探测并准备后备写法(改用捕获组捕获前缀与目标、或两步定位切片),移植到其他引擎时还要确认是否允许变长断言。

JS Unicode 模式下正则行为

JS Unicode 模式让正则按码点而非 UTF-16 码元处理文本,点号与量词不再拆开表情符号,并启用属性转义(需写完整属性名);未启用时属性转义会静默按字面文本匹配。该模式不改变简写类的 ASCII 语义,与另一集合运算标志互斥。

JS 命名捕获组的写法与兼容

JS 命名捕获组用小于号加组名声明,通过结果对象的命名分组属性取值,替换模板与模式内反向引用均可按名字引用。它属于较新特性,老环境不支持时字面量会导致解析期失败,因此公共代码需要做构造器能力探测或构建期转译。

PHP PCRE 函数的匹配流程

PHP 的 PCRE 相关函数按用途分为匹配、替换、切分与转义几类,使用时必须严格比较返回值以区分「未匹配」与「执行失败」,并用错误查询接口获取回溯上限等原因。未参与匹配的可选组在结果中是空字符串,与匹配到空内容无法区分。

PHP 正则定界符与修饰符

PHP 模式必须由定界符包裹,首字符即定界符、末尾需闭合,修饰符写在末尾定界符之后用于调整语义:i 忽略大小写、m 多行锚点、s 点号匹配换行、x 可读模式、u UTF-8、A 强制串首、D 严格串尾、U 反转贪心。模式内出现定界符必须转义或更换定界符。

PHP 全局匹配的排序标志

PHP 全局匹配用标志决定结果形状:默认按组聚合(先按组号再按匹配序号),另一标志按匹配聚合(每次匹配的字段打包在一起),还可附加偏移信息与空值区分标志。偏移按字节计,多字节文本下与字符索引不同,选错聚合标志不会报错但取值全错。

PHP 正则 Unicode 模式影响

PHP 正则的 UTF-8 修饰符让模式与主题按字符解析,点号与量词作用于完整字符,中文与表情处理更符合直觉,同时启用属性转义;但它不改变单词类与数字类的 ASCII 语义,主题串非合法 UTF-8 时会返回假值,长度与偏移仍按字节计算。

PHP 正则转义函数的使用

PHP 的转义函数把正则元字符加上反斜杠,是拼接用户输入与配置值时的必备步骤,第二个参数必须传入实际使用的定界符。它只适用于字面量,不可用于已经是模式的字符串,也不等同于替换模板的转义规则。

PHP 正则替换回调与引用

PHP 替换有模板引用与回调两种入口:模板支持序号与命名分组引用,回调接收匹配数组并由代码决定替换内容,是处理条件判断场景的正规做法。回调返回空值会删除匹配内容,替换失败返回假值需与空结果严格区分。

PHP 正则回溯上限调优

PHP 为 PCRE 设置了回溯与递归上限,超限时匹配函数返回假值并给出对应错误码,常见成因是嵌套量词叠加长输入。处理顺序是先重写模式消除重叠结构、再限制输入长度,调大上限只是临时缓解;所有调用处都必须严格比较返回值。

grep 基础与扩展正则的差异

grep 默认使用基础正则,分组、量词与交替需要转义;加选项切到扩展正则后这些写法直接可用,字面量反而需要转义。匹配以行为单位且是部分匹配,整行相符要用专门选项,另外实现的扩展写法会影响脚本可移植性。

grep 的 PCRE 模式适用场景

切换到 PCRE 模式可使用简写字符类、非贪婪量词、环视与重置匹配起点,适合复杂的临时提取,但属于实现扩展、可移植性差、对编码敏感且不能跨行匹配,并会重新引入回溯风险。脚本化前应评估是否改用可移植写法或线性引擎工具。

sed 正则方言与转义差异

sed 默认使用基础正则,分组与量词需要转义;切换扩展正则后这些写法可直接使用,替换部分的反向引用与引用符需要单独注意。不同实现对基础正则下的额外写法支持不一致,可移植脚本应显式选择语法并先输出确认再原地改写。

awk 正则匹配的方言特点

awk 的正则按扩展语法解释,用匹配与不匹配运算符区分字段、整行与变量,模式作为字符串传入时要多写一层反斜杠,多字符分隔符也按正则解释。主流实现提供的词边界与字符类简写属于扩展,可移植脚本应改用标准写法。

MySQL 正则匹配的语法范围

MySQL 正则运算符是部分匹配语义,整串校验必须自行加锚点;语法范围随版本变化,较新版本更换引擎后支持面扩大。大小写敏感性由字段排序规则决定,正则条件通常无法使用索引,大数据表上应先缩小候选集再筛选。

MySQL 新正则函数的用法差异

MySQL 新版本提供判断、定位、截取与替换四类正则函数,可用匹配类型参数控制大小写、多行与换行行为,原有运算符等价于判断函数。各函数未命中时的返回值不同(假值、0、空值、原串),升级引擎后需用真实数据对照验证历史语句。

ES 正则查询的语法与限制

Elasticsearch 的 regexp query 用 Lucene 自动机语法匹配单个词项,不是 PCRE:隐含整词匹配,不支持环视与反向引用,前导通配无法利用索引前缀,开销高且受 max_determinized_states 限制。

ES 脚本正则查询的实现方式

在 Elasticsearch 里做逐字符正则只能靠 script query 或 script_fields 配 Painless:Painless 内置 /regex/ 字面量、=~ 与 ==~ 操作符,底层是 Java 正则,逐文档执行且不走索引,必须靠外层过滤缩小候选集。

Java 正则匹配接口的调用方式

Java 正则用 Pattern 编译、Matcher 执行:Pattern 线程安全可复用,Matcher 有状态不可跨线程;字符串字面量要双写反斜杠,find 与 matches 语义不同,命名组与 streaming 结果流是较新版本的实用补充。

.NET 正则的特性与差异

.NET 的 System.Text.RegularExpressions.Regex 默认使用回溯引擎,支持可变长度后行断言、平衡组等少数引擎才有的能力;.NET 7 起提供线性的 NonBacktracking 模式,超时保护与源生成正则是生产可用的关键。

Go 正则引擎的能力边界

Go 的 regexp 包基于 RE2 自动机引擎,匹配时间与输入长度成线性关系,因此刻意不支持反向引用与环视;语法属 RE2 子集,字符类默认按 ASCII,处理 Unicode 需用 \p{...} 属性写法。

字符编码与 Unicode40 条

ASCII/GBK/UTF 系列、乱码修复、归一化

ASCII 编码表结构与表示范围

ASCII 是 7 位编码标准,用 0x00-0x7F 共 128 个码位表示控制字符、标点、数字与英文字母;UTF-8 与 GBK 都完整保留这段映射,所以判断文件是否 ASCII 兼容是排查乱码的第一步。

GBK 编码结构与双字节规则

GBK 是 GB2312 的双字节扩展:0x00-0x7F 保留 ASCII,汉字用首字节 0x81-0xFE 加第二字节 0x40-0xFE 表示,共收录两万余汉字;Windows 的 cp936 与它基本等价,遇上 UTF-8 混用就产生乱码。

中文编码标准的覆盖范围差异

GB2312、GBK、GB18030 是三代中文编码且逐级兼容:GB2312 收 6763 个汉字,GBK 扩到 20902 个,GB18030 用可变长结构覆盖 Unicode 全部码位,是唯一能代表中文全集的国标编码。

GB18030 四字节区编码原理

GB18030 的四字节区用「0x81-0xFE + 0x30-0x39 + 0x81-0xFE + 0x30-0x39」结构专门表示增补平面字符,解析时靠第二字节是否落在 0x30-0x39 判断长度;这是它相对 GBK 的关键扩展。

UTF-8 变长编码原理与规则

UTF-8 是 Unicode 的变长编码:一个码位用 1 到 4 字节表示,前 128 个码位与 ASCII 逐位相同,首字节的位模式表明序列长度,因此具备自同步能力,是文件与网络传输的默认选择。

UTF-8 字节数与首字节规律

UTF-8 的字节数由首字节高位的连续 1 个数决定:0xxxxxxx 为 1 字节、110 开头为 2、1110 开头为 3、11110 开头为 4,续字节一律 10 开头;判定长度只需看首字节,这是流式解码与边界校验的基础。

UTF-16 字节序与 BOM 标记

UTF-16 用 2 或 4 字节表示一个码位,因此存在大端与小端两种字节序;BOM(U+FEFF)写在流首用来声明序别,FF FE 表示小端、FE FF 表示大端,缺了它解码器就可能把整段内容读成乱码。

UTF-16 代理对与增补平面

UTF-16 的基本单元是 16 位码元,BMP 之外的字符要用一对高位代理(D800-DBFF)与低位代理(DC00-DFFF)组合表示;字符串长度按码元计数时,一个 emoji 会被算成 2,这是长度与截断 bug 的常见来源。

UTF-32 定长编码的适用场景

UTF-32 是每个码位固定 4 字节的定长编码,索引与切片是常数时间,代价是体积膨胀最多 4 倍;它主要用于内存中的算法实现与内部索引,不适合落盘或网络传输。

字节序标记 BOM 的含义与取舍

BOM 是写在字节流最开头的 U+FEFF,用来声明字节序(UTF-16/32)或弱标识 UTF-8;UTF-8 的 BOM 是 EF BB BF,规范建议不写,HTTP 头、JSON、shell 脚本等场景明确不应出现。

BOM 引发的乱码与解析错误

BOM 造成的故障有两类:被当成正文内容(首行多出不可见字符,比较与解析失败),以及被错误编码解释成可见乱码(UTF-8 的 EF BB BF 按 GBK 显示为「锘」、按 Latin-1 显示为「」)。

判断文件实际编码的思路

文件本身通常不记录编码,识别只能靠启发式:先看 BOM 与声明(XML/HTML/HTTP 头),再做 UTF-8 严格合法性校验,最后用字频统计猜测单字节编码;任何自动判断都必须在样本上验证,不能当作结论。

乱码的常见成因与分析方法

乱码的本质是字节与被套用的解码器不匹配;分析套路是先看字节、再定编码、最后还原,同时把「问号(已丢失)」「方块豆腐(字体缺字形,非编码问题)」「怪字串(可逆)」这三类现象区分开。

UTF-8 被按 GBK 解析的乱码

UTF-8 内容被按 GBK 解码是最典型的中文乱码:三字节汉字被按两字节切分,出现「你好」变「浣犲ソ」这类怪字串;只要没有经过替换丢失,把乱码串按 GBK 编码回字节、再按 UTF-8 解码即可还原。

中文被当作单字节编码的乱码

中文被当作单字节编码(Latin-1、Windows-1252 等)解析时,UTF-8 的每个字节被映射成一个西欧字符,出现「ä」「Â」这类重音怪串;只要字节没被替换丢失,这种乱码同样可以反向还原。

乱码修复的通用排查流程

乱码修复按固定流程走:备份原始字节 → 判断是否可逆(有无问号与替换符)→ 定位出错环节 → 在副本上做反向还原实验 → 小批量验证 → 全量执行并回归;顺序错了会把可逆问题变成永久损坏。

二次编码导致的乱码识别

二次编码乱码来自同一段文本被连续套用两套编码规则:常见形态是「UTF-8 被按 GBK 读出后再按 GBK 或 Latin-1 写回」,结果是乱码之上再叠一层乱码,能否还原取决于中间每一步是否有信息丢失。

编码转换顺序引起的差异

转码是有方向的映射而非对称的字节变换:A→B→A 不一定回到原样,A→B 再 B→C 与 A→C 也可能结果不同,因此转码顺序、次数与目标编码的选择都会改变最终内容。

命令行转码工具的使用思路

iconv 是命令行编码转换的标准工具:用 -f 指定源编码、-t 指定目标编码,先确认源编码、先严格校验、输出到新文件而不是就地覆盖,是安全转码的三条基本纪律。

转码失败字符的处理策略

转码失败有两类原因:输入字节在源编码下非法,或字符在目标编码中无法表示;对应的处理策略是忽略、音译或中止,但任何「忽略」都意味着数据静默丢失,只能用在确认可接受的场合。

Python 编解码接口的正确用法

Python 3 把字符串与字节严格分成 str 和 bytes,转换必须显式调用 encode/decode;默认编码随环境变化,因此文件与标准输入输出都要显式指定 encoding,否则换机器就会出现乱码或报错。

Python 编解码错误的处理策略

Python 编解码的 errors 参数决定非法数据怎么处理:strict 抛异常适合校验,replace 用于展示层,surrogateescape 能保留原始字节,ignore 会静默丢数据;选错策略是数据静默损坏的常见来源。

数据库连接字符集不一致排查

MySQL 的字符集分三层:服务器/库表列、连接层(client、connection、results)、以及客户端实际发送的字节;连接声明与实际字节不符,就会出现「存进去是怪串」的双重编码乱码。

网页字符集声明与解析顺序

网页字符集按固定优先级判定:BOM 高于 HTTP 响应的 charset,HTTP 头又高于页面内的 meta 声明,meta 还必须在文档前 1024 字节内才有效;三者不一致是页面乱码的经典原因。

Unicode 码点与字符的关系

码点是 Unicode 给每个字符分配的抽象编号,写作 U+XXXX,范围 U+0000 到 U+10FFFF;它与字符在文件中的字节表示无关,也不等于用户看到的「一个字」,因为一个可见字符可能由多个码点组合而成。

Unicode 平面与区块划分

Unicode 的码位空间分成 17 个平面,每平面 65536 个码位:平面 0 是基本平面,平面 1 含 emoji 与古文字,平面 2、3 是 CJK 扩展生僻汉字,平面 14 与 15/16 分别用于特殊用途与私用区。

Unicode 通用类别与字符判定

Unicode 通用类别把每个码位归入字母、标记、数字、标点、符号、分隔符、其他七大类(细分到 Lu、Ll、Nd、Mn 等子类),是正则 \p{...}、字符校验与文本切分的通用依据。

NFC 归一化与组合字符合并

NFC 是合成式归一化:把基字符与组合标记合并成预组合字符(é 合成一个码点),是 Web 与多数存储场景的推荐形式,能减少长度与比较上的意外差异。

NFD 分解归一化的影响

NFD 是分解式归一化:把预组合字符拆成基字符加组合标记,便于按基字符检索与处理,但会改变码点数量与字节长度,且与 NFC 形式的字符串不相等。

归一化不一致导致的比较失败

同一段文字用 NFC 与 NFD 表示时码点不同,直接比较会得到「看起来一样却不相等」的结果;比较、去重、唯一约束之前必须先把两侧统一到同一归一化形式。

四种等价形式的区别与选择

Unicode 定义了四种归一化形式:NFC 与 NFD 处理规范等价(重音与组合标记),NFKC 与 NFKD 进一步处理兼容等价(全角、连字、上标等),前者适合存储与比较,后者适合检索与清洗。

归一化引发的安全绕过问题

归一化引发的安全问题来自「校验与使用不是同一个字符串」:攻击者用同形不同码点的字符(组合标记、兼容字符、视觉相似字符)绕过黑名单或伪造重复账号,防御要点是在归一化之后统一校验。

东亚字符宽度与对齐问题

东亚字符宽度指同一字符在不同上下文占 1 格还是 2 格显示:汉字与全角符号通常占 2 格,ASCII 占 1 格,组合标记占 0 格;终端对齐、表格排版与截断都必须按显示宽度而不是字节数或码点数计算。

emoji 编码构成与码点范围

emoji 是被吸收进 Unicode 的普通字符,主要位于 U+1F300-U+1FAFF 等区块;BMP 内为 3 字节(UTF-8)或 1 个编码单元(UTF-16),增补平面为 4 字节或 2 个编码单元,存储需 utf8mb4 级别的支持。

emoji 组合序列与连接符

ZWJ 组合序列用零宽连接符 U+200D 把多个 emoji 连成一个整体(家庭、职业、情侣等),码点上是多个字符、视觉上是一个字符;处理这类内容必须按序列整体计算与截断,否则会被拆散。

emoji 字数统计的正确做法

统计 emoji 字数要按字形簇而不是字节数、码点数或 UTF-16 编码单元数:带肤色、ZWJ 组合与旗帜的 emoji 由多个码点组成却应算 1 个字符,用错口径会导致长度校验误判与截断事故。

字形簇概念与字符切分方法

字形簇是用户感知的一个字符单位,可能由多个码点组成(基字符加组合标记、带肤色的 emoji、ZWJ 组合序列、旗帜);文本切分、计数与删除都应依据 Unicode 字形簇边界规则,而不是按码点或编码单元切。

Unicode 大小写映射的复杂性

Unicode 大小写映射比 ASCII 复杂:存在一映射多(一个字符变大写后长度改变)、上下文相关(希腊语词尾 sigma)、语言相关(土耳其语 i)以及大小写折叠(casefold)这套专门用于比较的规则。

Unicode 排序规则与区域差异

Unicode 排序不是单纯的码点大小比较:标准排序算法先把字符串映射成多级权重(主权重管字母、次权重管重音、三级管大小写),再逐级比较,并按语言做顺序调整,所以排序应使用 collation 实现而不是字符串比较。

Unicode 属性在正则中的使用

Unicode 属性类让正则按字符属性匹配:\p{L} 匹配任意字母、\p{Han} 匹配汉字、\p{Script=Latin} 限定文字系统;是否支持、写法与大小写敏感度依引擎而不同,是不确定时最容易出错的一类语法。

编码转换与格式35 条

Base64、URL 编码、实体转义、进制与时间格式

Base64 编码原理与位数映射

Base64 把二进制数据映射为 64 个可打印字符:每 3 个字节(24 位)拆成 4 个 6 位组,各对应一个字符,输出体积约增加三分之一;它只做表示法转换,既不加密也不压缩。

Base64 填充字符规则与长度

Base64 的填充符 = 用来补足 4 的倍数:输入余 1 字节补两个等号、余 2 字节补一个、余 0 不补;不少场景(URL 安全变体、令牌)会省略填充,解码前必须补齐。

Base64 URL 安全变体的差异

URL 安全变体(base64url)把标准字母表里的加号与斜杠换成减号与下划线,并常省略填充,专为避免 URL 与文件名中的字符冲突;它与标准 Base64 字母表不同,混用会直接解码失败。

Base64 解码失败的常见原因

Base64 解码失败的常见原因有五类:混入非法字符(换行、空格、URL 变体字符)、长度不是 4 的倍数、填充不完整、字母表用错、内容被截断;逐项检查能快速定位。

多次 Base64 嵌套的识别方法

多次 Base64 嵌套会让内容看起来像随机字母串:每一轮都增加约 33% 体积并把首字符限制在字母表内;识别方法是看字符集是否纯净、长度是否为 4 的倍数,并按可读性变化判断何时停止解码。

Base64 体积膨胀率与取舍

Base64 的体积开销固定约为三分之一(输出长度为输入的 4/3 并向上取整到 4 的倍数);内联大文件会同时放大存储、带宽与内存占用,超过一定规模应改用二进制通道。

URL 百分号编码的原理

百分号编码把字符先按 UTF-8 编成字节、再对不允许出现的字节写成 %加两位十六进制;允许出现的字符集随 URL 组件不同而不同,因此编码范围要按组件确定,不能一套规则用到底。

URL 保留字符该不该编码

URL 保留字符该不该编码取决于用途:作为分隔符时必须保持原样,作为数据时必须编码;未保留字符永不编码,百分号自身作为数据要写成 %25,混用会造成参数被拆分或签名不一致。

URL 中空格的编码处理

空格有三种写法:%20 在 URL 任何位置都正确,+ 只在表单编码(查询串与表单体)中代表空格,字面空格非法;路径中的 + 不是空格,混用是大量参数与路径 bug 的根源。

URL 重复编码问题排查

重复编码的特征是百分号本身被转义:%E4%B8%AD 变成 %25E4%25B8%25AD,解码一次后仍是编码形式;原因是链路中编码环节被叠加两次,修复要在数据与链路上同时进行。

查询参数编码的范围与坑

查询参数要按「键与值分别编码、再用 & 与 = 组装」的方式处理:数组与重复键的表示各框架不同,空值与缺参数语义不同,参数顺序在签名场景还会影响结果。

表单编码与 JSON 请求差异

表单编码与 JSON 请求体的差别集中在四点:内容类型声明不同、编码规则不同(表单把空格写作 +,JSON 不会)、结构表达能力不同(JSON 支持嵌套与类型,表单只有键值)以及字符集约定不同。

HTML 实体引用的写法与含义

HTML 实体引用用 ASCII 表达其他字符:命名形式(&copy;)、十进制(&#169;)、十六进制(&#xA9;);核心用途是把 & < > 与引号转义成不参与标签解析的形式,避免内容被当成标记。

HTML 实体转义与注入防护

转义要按输出上下文选择规则:HTML 文本内容转 & 与尖括号,属性值还要处理引号,URL 与脚本、样式上下文各有编码方式;只用一套规则处理所有位置,正是注入类漏洞的常见来源。

HTML 命名实体与数字实体

命名实体可读性好但依赖规范版本(HTML 定义了大量名字,XML 只有五个内置),数字实体(十进制 &#169; 或十六进制 &#xA9;)可表示任意 Unicode 码点;需要覆盖性与一致性时用数字形式,追求可读性时用命名形式。

HTML 实体解码的常见陷阱

HTML 实体解码由解析器在词法阶段完成,常见坑包括二次解码、无分号命名实体、C1 区数字实体回退以及属性上下文差异;正确做法是只在数据入口用标准解析器解码一次,输出时按上下文重新编码。

JSON 字符串转义规则要点

JSON 字符串只有双引号、反斜杠和 U+0000 至 U+001F 控制字符必须转义,合法转义固定为几个简写加 \uXXXX;单引号、\x、注释、尾逗号都是语法错误,工程上应交给标准 JSON 编码器生成而非手工拼接。

JSON 中的 Unicode 转义写法

JSON 的 \uXXXX 转义表示 UTF-16 码元,非 BMP 字符需用高位与低位两个代理对书写;JSON 本身允许 UTF-8 原文字符,转义主要服务于纯 ASCII 通道;孤立代理在语法层合法但行为不可预测,应视为脏数据。

JS 字符串转义与 JSON 差异

JS 字符串字面量允许单引号、\xHH、\u{码点}、行末续行与模板字符串,未知转义还会静默退化;JSON 只认固定几个转义且必须双引号。把 JS 字面量交给 JSON 解析器必然报错,稳妥做法是用序列化器互转。

CSS 转义序列的写法与用途

CSS 反斜杠转义分两类:跟非十六进制字符表示该字符本身,跟 1 到 6 位十六进制表示一个 Unicode 码点,可用空白收尾。它用于书写含特殊字符的选择器与 content 文本,外部数据拼选择器应优先用 CSS.escape()。

Shell 引号与转义层叠问题

Shell 转义的关键是分清「Shell 层」与「命令层」两级解释:单引号全字面量、双引号仍展开变量与命令替换、$'...' 提供控制字符、here-doc 用带引号的定界符关闭展开。传参一律用 "$var",不要拼接外部输入再执行。

CSV 字段转义与分隔符冲突

CSV 字段含分隔符、双引号或换行时必须整体加双引号并把内部双引号翻倍,这是 RFC 4180 的核心约定;此外要防公式注入、前导零丢失与分隔符/编码不匹配,生成与解析都应交给标准库而非手工拼接。

XML 特殊字符转义规则

XML 只预定义 &lt;、&gt;、&amp;、&quot;、&apos; 五个实体且必须带分号,实际必须转义的是 & 与 <;转义要先处理 &,禁用字符无法用数字实体绕过,解析外部 XML 还需防 XXE。

Unicode 转义表示法的对比

Unicode 转义按单位分三类:\uXXXX 走 UTF-16 码元,\u{}、\UXXXXXXXX、HTML 数字实体与 CSS 转义走码点,百分号编码走 UTF-8 字节。混用会让字符被截断或拼错,传递前先确认单位与补位规则。

十六进制实体与字符互转

HTML 十六进制数字实体形如 &#x4E2D;,本质是码点的十六进制写法,可与十进制实体、命名实体混用;双向转换按码点运算即可,注意至少补齐 4 位、避免二次编码,且 script/style 等原始文本元素内不做实体解码。

进制转换的基本方法与验证

进制转换靠位权展开与除基取余两条基本方法,2 的幂进制之间可按 3 位、4 位分组互换;工程上的坑集中在基数推断(前导零被当八进制)、位宽、符号位与浮点精度,解析时显式声明基数并用往返转换验证。

二进制十六进制十进制互转

二进制与十六进制按 4 位对 1 位互换,一个字节即两位十六进制;十进制转换靠位权展开或除基取余。实际排错要先分清数值层与字节层:进制决定写法,字节序与位宽决定解释结果,前导零与符号位是最常见的两处错误来源。

十六进制数据阅读与还原

十六进制转储按行分三段:偏移、字节、可打印视图,默认每行 16 字节,阅读时以左侧十六进制偏移定位字段、以每两个十六进制数字为一字节读数;识别类型看文件头魔数,还原数据必须用 xxd -r 之类工具并校验长度。

位标志位编码与解码思路

位标志用 2 的幂次掩码把多个开关压进一个整数:判位用按位与、置位用按位或、清位用按位与取反、切换用异或,多位字段先右移再掩码。最容易出错的是运算符优先级、有符号右移与超过 32 位时的精度限制。

时间戳与可读时间的互转

Unix 时间戳是以 1970-01-01T00:00:00Z 为原点的秒计数,本身是 UTC 时刻、不计闰秒,显示时才套用时区。互转要用专用函数,注意单位、时区与 32 位溢出边界,不同体系的时间起点也不同。

时间戳秒与毫秒单位的识别

识别时间戳单位先数位数——秒 10 位、毫秒 13 位、微秒 16 位、纳秒 19 位,再用合理年份区间交叉验证;浏览器 Date 要毫秒、date 命令的 @ 参数要秒,数据库 32 位整型装不下毫秒时间戳。

ISO 8601 时间格式书写规范

ISO 8601 用固定宽度、从大到小的顺序书写日期时间,日期与时间用 T 分隔,末尾以 Z 或正负偏移表示时区;固定宽度使同时区的字符串可直接排序。工程上要明确采用扩展格式还是基本格式、是否强制偏移,并在比较前统一换算到 UTC。

时区偏移量的书写与换算

时区偏移量是本地时间与 UTC 的差值,向东为正,写作正负号加时分,Z 表示零偏移;它只是某一时刻的快照,时区的完整规则由时区数据库定义。跨系统传递用偏移量或时区名而非三字母缩写,存储建议统一为 UTC 并在展示层换算。

日期时间格式互换的规范做法

时间格式互换应走「解析成结构化时刻、在结构化层运算、再按目标格式输出」三步,而不是字符串替换;各体系记号的大小写与含义不同(POSIX 的 %M 是分、Java 的 MM 是月),Go 用固定参考时间做模板。

时间戳精度丢失与位数溢出

双精度整数的安全上限约 9.007 乘 10 的 15 次方,毫秒时间戳安全、微秒接近边界、纳秒必然丢末位;跨系统传递应使用十进制字符串、BigInt 或「秒 + 纳秒」字段对,数据库层面需 64 位整型或带小数秒精度的时间类型。

没有匹配的条目。换个关键词试试,或直接全站搜索。
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌‌‌​‌‌​​‌​‌​‌‌‌‌​​​​​‌​‌‌‌‌