1 min read · 219 words
最近在做文本批量替换时,被 PowerShell 哈希表的 Duplicate keys 报错卡住了。本文记录我如何绕过 PowerShell 默认不区分大小写的坑,快速搞定业务需求的排查与解决过程。
问题背景
当时我需要用 PowerShell 批量替换文档中特定的 Hex 颜色值。由于源文档中的 Hex 颜色值大小写混杂,为了做好映射,我定义了如下的哈希表(Hashtable):
$replacements = @{'#1e2a45'='#f6f7f8'; '#1E2A45'='#f6f7f8'}结果刚一运行,脚本就在定义哈希表这一步直接崩了。
报错现象
终端直接抛出以下错误信息:
Duplicate keys '#1E2A45' are not allowed in hash literals原因分析:PowerShell 默认的哈希表 Key 是不区分大小写(case-insensitive)的。因此,它把 #1e2a45 和 #1E2A45 识别成了同一个 Key,判定为重复定义,直接抛出异常。
运行环境
- OS: Windows
- 工具版本: Windows PowerShell 5.1
- 自动化技术栈: hashtable literal (@{})
尝试过但失败的方案
我最开始想到的绕过方法是不用字面量语法(@{}),而是直接调用 .NET 对象:New-Object System.Collections.Hashtable。然而,这玩意儿底层依然走的是不区分大小写的比较机制,换汤不换药,照样报错。
折腾了半天,PowerShell 就是不听劝。既然工具脾气硬,咱也没必要死磕,果断换思路。
最终解决方案
既然 PowerShell 这么别扭,我决定直接用文本处理更灵活的 Python 曲线救国。利用 Python 的 re 模块,配合 re.compile(re.escape(old), re.I) 实现忽略大小写的正则匹配。这样就能一次性安全地把所有大小写混杂的 Hex 颜色值全部替换掉。
核心代码
# 待替换映射列表
swaps = [
('#1e2a45', '#f6f7f8'),
('#1E2A45', '#f6f7f8')
]
# 执行忽略大小写的替换
for old, new in swaps:
pat = re.compile(re.escape(old), re.I)
content = pat.sub(new, content)验证结果
运行 Python 脚本后,仅执行了一次,就完美完成了全部 131 个 Hex 值的替换。没有再报任何重复 Key 的错误,收工。
当前状态
Fixed (已解决)
写在最后
如果你也遇到了 PowerShell hashtable duplicate keys 的报错,听我一句劝,别在 PowerShell 里费劲去折腾什么复杂的 .NET Dictionary 声明了。如果是文本替换类的任务,直接上 Python 配合 re.I,省时省力,对精神健康大有裨益。
Category Coverage Notice
This article follows our label-specific editorial criteria. Details: