PowerShell参数解析

更新于 2025-10-06

一、解析参数 - 方法

能够将传入的参数数组分为三类:选项(Options)、开关(Switches)、原始参数(Raws)。通常用于自定义脚本工具,简化命令行参数的处理。

function ParseArguments($arguments){
    $options = @{};
    $switches = @();
    $raws = @();
    for($i=0; $i -lt $arguments.Length; $i++){
        $arg = $arguments[$i]
        if($arg -like "--*"){
            if($i -eq ($arguments.Length - 1)) {
                $switches += $arg;
                continue;
            }
            $nextValue = $arguments[$i + 1];
            if($nextValue -like "--*"){
                $switches += $arg;
                continue;
            }
            $options[$arg] = $nextValue
            $i++;
            continue;
        }
        if($arg -like "-*"){
            $switches += $arg;
            continue;
        }
        $raws += $arg;
    }
    return @{
        Options=$options
        Switches=$switches
        Raws=$raws
    };
}

优缺点

  • 优点:简单、易用,能够处理大多数常见参数模式。
  • 缺点
    • 不支持参数组(如 -abc 拆分为 -a -b -c)。
    • 仅支持单层选项值,不支持 --opt=value 这种格式。
    • 对于带空格的参数需要谨慎传递(如 "--name", "foo bar")。

二、解析参数 - 类

用于解析和封装命令行参数,并提供便捷的查询方法。相比前面的函数版,类的实现更面向对象,功能更完整。

class Arguments {
    hidden [hashtable]$options = @{};
    hidden [array]$switches = @();
    hidden [array]$raws = @();

    Arguments ([array]$arguments) {
        for($i=0; $i -lt $arguments.Length; $i++){
            $arg = $arguments[$i]
            if($arg -like "--*"){
                $arg = $arg.substring(2)
                if($i -eq ($arguments.Length - 1)) {
                    $this.switches += $arg;
                    continue;
                }
                $nextValue = $arguments[$i + 1];
                if($nextValue -like "--*"){
                    $this.switches += $arg;
                    continue;
                }
                $this.options[$arg] = $nextValue
                $i++;
                continue;
            }
            if($arg -like "-*"){
                $arg = $arg.substring(1)
                $this.switches += $arg;
                continue;
            }
            $this.raws += $arg;
        }
    }

    [string]GetOption([string]$key, [string] $defaultValue){
        return $this.options[$key] ?? $defaultValue;
    }
    [string]GetRaw([int]$index){
        return $this.raws[$index];
    }
    [boolean]HasOption([string]$key){
        return $this.options.Keys -contains $key;
    }
    [boolean]NotHasOption([string]$key){
        return $this.options.Keys -notcontains $key;
    }
    [boolean]HasSwitch([string]$key){
        return $this.switches -contains $key;
    }
    [boolean]HasSwitchCi([string]$key){
        return $this.switches -ccontains $key;
    }
    [boolean]NotHasSwitch([string]$key){
        return $this.switches -notcontains $key;
    }
    [boolean]NotHasSwitchCi([string]$key){
        return $this.switches -cnotcontains $key;
    }
}

优缺点

优点:

  • 面向对象封装,易于扩展和复用。
  • 参数前缀与存储解耦,查询时只需关注实际参数名。
  • 支持大小写敏感和不敏感开关判断。
  • 提供默认值查询选项,更灵活。

缺点:

  • 选项值只支持下一项为值,不支持 --key=value 格式。
  • 未处理参数组(如 -abc)。
  • 没有对参数合法性做进一步检查(如重复参数)。
  • 仅适用于 PowerShell 5/7+(部分语法如 ?? 仅支持新版本)。
浙ICP备19039918号-1