PowerShell输入格式化脚本异常求助:无法实现5-3-3-3的分组分隔格式
修复PowerShell序列号格式化脚本的分组问题
首先得感谢u/frmadsen的前期协助!咱们来搞定这个分组长度不切换的问题——原脚本的核心问题出在分组大小切换的逻辑混乱,还错误地重置了输入字符串,直接导致后续的分组规则完全失效。
问题根源分析
原脚本里有两段几乎一模一样的if判断,而且第二段里误写了$inputString = 0,直接清空了用户输入的内容;同时分组大小切换的时机也不对:本该在第一个5字符分组完成后,把后续分组固定为3字符,结果重复触发了添加分隔符的逻辑,自然出不来预期的格式。
修正后的完整代码
[Console]::TreatControlCAsInput = $true [Console]::WriteLine("Enter Serial:") $inputString = "" $groupSizes = @(5, 3, 3, 3) # 明确指定每个分组的长度:5-3-3-3 $currentGroupIndex = 0 $maxLength = ($groupSizes | Measure-Object -Sum).Sum + ($groupSizes.Count - 1) # 计算总长度(含分隔符) $abort = $false do{ $keyInfo = [Console]::ReadKey($true) # 处理ESC键退出程序 if($keyInfo.Key -eq "Escape"){ $abort = $true break } # 忽略Alt/Ctrl组合键、Tab和空字符 if(($keyInfo.Modifiers -band [System.ConsoleModifiers]::Alt) -eq [System.ConsoleModifiers]::Alt -or ($keyInfo.Modifiers -band [System.ConsoleModifiers]::Control) -eq [System.ConsoleModifiers]::Control -or $keyInfo.Key -eq "Tab" -or $keyInfo.KeyChar -eq "`0"){ continue } # 处理退格键,同时维护分组索引 if($keyInfo.Key -eq "Backspace"){ if($inputString.Length -ge 1){ $oldLength = $inputString.Length $removeLen = 1 $isRemovingSeparator = $inputString.EndsWith('-') # 如果删除的是分隔符,要同时删掉分隔符和前一个字符,并且回退分组索引 if($isRemovingSeparator){ $removeLen = 2 $currentGroupIndex-- # 确保分组索引不会小于0 if($currentGroupIndex -lt 0){ $currentGroupIndex = 0 } } else { # 删除普通字符时,检查是否回到上一个分组的末尾,调整分组索引 $cleanInput = $inputString.Replace('-', '') $charsInCurrentGroup = ($cleanInput.Length % $groupSizes[$currentGroupIndex]) if($charsInCurrentGroup -eq 0 -and $currentGroupIndex -gt 0){ $currentGroupIndex-- } } $cursorCol = [Console]::CursorLeft - $removeLen $inputString = $inputString.Substring(0, $oldLength - $removeLen) # 清空当前行并重新输出内容,保证显示正确 [Console]::CursorLeft = 0 [Console]::Write($inputString + ' '*($oldLength - $inputString.Length)) [Console]::CursorLeft = $cursorCol } continue } # 超出最大允许长度就忽略输入 if($inputString.Length -ge $maxLength){ continue } $lastChar = $keyInfo.KeyChar # 可选:只允许输入字母数字,避免无效字符干扰格式(不需要可以删掉这段) if(-not $lastChar -match '[a-zA-Z0-9]'){ continue } [Console]::Write($lastChar) $inputString += $lastChar # 计算去掉分隔符后的真实字符数,判断是否需要添加分隔符 $cleanLength = $inputString.Replace('-', '').Length $currentGroupSize = $groupSizes[$currentGroupIndex] if($cleanLength % $currentGroupSize -eq 0 -and $currentGroupIndex -lt ($groupSizes.Count - 1)){ $inputString += '-' [Console]::Write('-') $currentGroupIndex++ } }while($keyInfo.Key -ne "Enter") [Console]::WriteLine("") if(!$abort){ "User wrote: $inputString" }else{ "User aborted" }
关键修改说明
- 明确分组规则:用
$groupSizes = @(5, 3, 3, 3)直接定义每个分组的长度,逻辑一目了然,再也不会出现分组大小乱切换的问题。 - 修复退格逻辑:退格时不仅处理字符删除,还会根据当前输入位置调整分组索引,确保退格后再次输入时,分组规则依然正确。
- 移除致命错误代码:删掉了原脚本中
$inputString = 0这段清空输入的错误逻辑。 - 准确计数有效字符:通过去掉分隔符后的字符数判断分组进度,保证添加分隔符的时机完全准确。
- 可选输入校验:增加了只允许字母数字输入的判断,避免用户输入无效字符破坏格式(不需要的话可以直接删掉这段)。
现在脚本就能完美生成aaaaa-bbb-ccc-ddd的格式,退格操作也能正常维护分组规则啦!
内容的提问来源于stack exchange,提问作者Seth
相关产品推荐
相关产品推荐

