You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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" 
}

关键修改说明

  1. 明确分组规则:用$groupSizes = @(5, 3, 3, 3)直接定义每个分组的长度,逻辑一目了然,再也不会出现分组大小乱切换的问题。
  2. 修复退格逻辑:退格时不仅处理字符删除,还会根据当前输入位置调整分组索引,确保退格后再次输入时,分组规则依然正确。
  3. 移除致命错误代码:删掉了原脚本中$inputString = 0这段清空输入的错误逻辑。
  4. 准确计数有效字符:通过去掉分隔符后的字符数判断分组进度,保证添加分隔符的时机完全准确。
  5. 可选输入校验:增加了只允许字母数字输入的判断,避免用户输入无效字符破坏格式(不需要的话可以直接删掉这段)。

现在脚本就能完美生成aaaaa-bbb-ccc-ddd的格式,退格操作也能正常维护分组规则啦!

内容的提问来源于stack exchange,提问作者Seth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:48:14