在 PowerShell 中安全地将字符串转换为布尔值

问题描述 投票:0回答:7

我正在尝试将 PowerShell 脚本的参数转换为布尔值。这条线

[System.Convert]::ToBoolean($a)

只要我使用有效值(例如“true”或“false”)就可以正常工作,但是当传递无效值(例如“bla”或“”)时,会返回错误。我需要类似于 TryParse 的东西,如果输入值无效,它只会将值设置为 false 并返回一个指示转换成功或失败的布尔值。 作为记录,我尝试了 [boolean]::TryParse 和 [bool]::TryParse,PowerShell 似乎无法识别它。

现在我不得不通过两个额外的 if 语句来笨拙地处理这个问题。

令我惊讶的是,到目前为止我发现的操作方法和博客文章都没有涉及无效值。 我是否遗漏了什么,或者 PowerShell 小孩子对于输入验证来说太酷了?

powershell boolean tryparse
7个回答
34
投票
只要您使用

TryParse

 并首先声明变量,
ref
就应该可以工作:

$out = $null
if ([bool]::TryParse($a, [ref]$out)) {
    # parsed to a boolean
    Write-Host "Value: $out"
} else {
    Write-Host "Input is not boolean: $a"
}

33
投票

您可以使用 try / catch 块:

$a = "bla"
try {
  $result = [System.Convert]::ToBoolean($a) 
} catch [FormatException] {
  $result = $false
}

给予:

> $result
False

10
投票
$a = 'bla'
$a = ($a -eq [bool]::TrueString).tostring()
$a

False

4
投票

另一种可能性是使用 switch 语句并仅评估

True
1
default

$a = "Bla"
$ret = switch ($a) { {$_ -eq 1 -or $_ -eq  "True"}{$True} default{$false}}

在此,如果字符串等于

True
,则返回
$true
。在所有其他情况下,都会返回
$false

另一种方法是这样的:

@{$true="True";$false="False"}[$a -eq "True" -or $a -eq 1]

来源 PowerShell 中的三元运算符,作者:Jon Friesen


3
投票

只是再次寻找这个并找到了我自己的答案 - 但作为评论,因此添加了一些更正/其他输入值作为答案,并且还进行了纠缠测试以验证其按预期工作:

Function ParseBool{
    [CmdletBinding()]
    param(
        [Parameter(Position=0)]
        [System.String]$inputVal
    )
    switch -regex ($inputVal.Trim())
    {
        "^(1|true|yes|on|enabled)$" { $true }

        default { $false }
    }
}

Describe "ParseBool Testing" {
    $testcases = @(
        @{ TestValue = '1'; Expected = $true },
        @{ TestValue = ' true'; Expected = $true },
        @{ TestValue = 'true '; Expected = $true },
        @{ TestValue = 'true'; Expected = $true },
        @{ TestValue = 'True'; Expected = $true },
        @{ TestValue = 'yes'; Expected = $true },
        @{ TestValue = 'Yes'; Expected = $true },
        @{ TestValue = 'on'; Expected = $true },
        @{ TestValue = 'On'; Expected = $true },
        @{ TestValue = 'enabled'; Expected = $true },
        @{ TestValue = 'Enabled'; Expected = $true },

        @{ TestValue = $null; Expected = $false },
        @{ TestValue = ''; Expected = $false },
        @{ TestValue = '0'; Expected = $false },
        @{ TestValue = ' false'; Expected = $false },
        @{ TestValue = 'false '; Expected = $false },
        @{ TestValue = 'false'; Expected = $false },
        @{ TestValue = 'False'; Expected = $false },
        @{ TestValue = 'no'; Expected = $false },
        @{ TestValue = 'No'; Expected = $false },
        @{ TestValue = 'off'; Expected = $false },
        @{ TestValue = 'Off'; Expected = $false },
        @{ TestValue = 'disabled'; Expected = $false },
        @{ TestValue = 'Disabled'; Expected = $false }
    )


    It 'input <TestValue> parses as <Expected>' -TestCases $testCases {
        param ($TestValue, $Expected)
        ParseBool $TestValue | Should Be $Expected
    }
}

3
投票

之前的答案更完整,但如果您知道

$foo -eq 1, "1", 0, "0", $true, $false...
任何可以强制为
[int]

以下任一

statements
有效:

[System.Convert]::ToBoolean([int]$foo)
[System.Convert]::ToBoolean(0 + $foo)

希望能帮助那些只需要简单解决方案的人。


0
投票

如果您有一个要考虑的字符串列表

true
,一个简单的单行方法是使用
-eq
的属性,输出左侧列表中与右侧匹配的任何成员手边:

$boolValue = ('1', 'True', 'true', 'yes', 'Yes' -eq $testValue).Length -gt 0

任何其他都会被考虑

False

如果您的输入可能不是

string
数据类型,结果可能不符合预期!

© www.soinside.com 2019 - 2024. All rights reserved.