Batch脚本实现Percent Encoding保留字符替换的问题解决
问题原因
- 感叹号
!读取丢失:脚本启动时就开启了延迟扩展,输入内容中的!会被系统识别为延迟变量的边界标识符,直接被过滤丢弃,不会存入变量。 - 三处替换失效的根因:
!:延迟扩展模式下!属于特殊控制符,直接写在变量替换语法中会被解析为控制符,无法匹配字面量感叹号*:批处理原生变量替换中*是通配符,默认匹配从字符串开头到指定字符的全部内容,无法作为普通字符匹配=:批处理变量替换语法使用=作为搜索串和替换串的分隔符,直接写在搜索位会被识别为语法分隔符,无法匹配字面量等号
解决方案
采用「关闭延迟扩展读取输入 + 逐字符遍历查表替换」的方案,完全避开原生变量替换的特殊字符语法限制,可覆盖所有保留字符的替换需求。
完整可运行代码
@echo off setlocal disableDelayedExpansion :: 预清空输入变量,避免空输入复用旧值 set "pass=" set /p "pass=Enter pass: " :: 预定义字符与编码的映射表 set "map[!]=%%21" set "map[#]=%%23" set "map[$]=%%24" set "map[%%]=%%25" set "map[&]=%%26" set "map[']=%%27" set "map[(]=%%28" set "map[)]=%%29" set "map[*]=%%2A" set "map[+]=%%2B" set "map[,]=%%2C" set "map[/]=%%2F" set "map[:]=%%3A" set "map[;]=%%3B" set "map[=]=%%3D" set "map[?]=%%3F" set "map[@]=%%40" set "map[[]=%%5B" set "map[]]=%%5D" :: 开启延迟扩展进行字符遍历替换 setlocal enableDelayedExpansion set "result=" :: 逐位读取字符,最大支持1024长度的输入,可自行调整上限 for /l %%i in (0,1,1023) do ( if "!pass:~%%i,1!"=="" goto endLoop set "char=!pass:~%%i,1!" :: 匹配映射表替换,无匹配则保留原字符 if defined map[!char!] ( set "result=!result!!map[!char!]!" ) else ( set "result=!result!!char!" ) ) :endLoop :: 输出最终编码结果 echo !result! pause endlocal endlocal
效果说明
使用测试字符串Test ! # $ % ' ( ) * + , / : ; = ? @ [ ]输入测试,可输出所有保留字符替换完成的百分号编码结果,无字符丢失、替换失效问题。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

