web-dev-qa-db-ja.com

PowerShellで文字列をブールに安全に変換する

PowerShellスクリプトの引数をブール値に変換しようとしています。この線

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

「true」や「false」などの有効な値を使用している限り問題なく機能しますが、「bla」や「」などの無効な値が渡されると、エラーが返されます。 TryParseに似たものが必要です。入力値が無効な場合に値をfalseに設定し、変換の成功または失敗を示すブール値を返します。参考までに、[boolean] :: TryParseおよび[bool] :: TryParseを試しましたが、PowerShellで認識されないようです。

現在、2つのifステートメントを追加することで、これを不器用に処理する必要があります。

驚いたことに、これまでに見つけたハウツーやブログの投稿では無効な値を扱っていません。何か不足しているのでしょうか、それともPowerShellの子供たちは入力の検証には単純すぎますか?

14
Shaggydog

あなたはtry/catchブロックを使うことができます:

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

与える:

> $result
False
18
arco444

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"
}
15
Mike Zboray
$a = 'bla'
$a = ($a -eq [bool]::TrueString).tostring()
$a

False
6
mjolinor

もう一度これを探して、自分の答えを見つけました-しかし、コメントとして、いくつかの修正/その他の入力値を含む回答として追加し、それが期待どおりに機能することを確認するためのテストテストも追加しました。

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
    }
}
2
David Wallis

もう1つの可能性は、スイッチのステートメントを使用して、True1および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]

ソース Jon FriesenによるPowerShellの三項演算子

2

以前の回答はより完全ですが、知っている場合は$foo -eq 1, "1", 0, "0", $true, $false...に強制できるすべてのもの[int]

次のいずれかのstatements作業:

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

単純なソリューションが必要な人を助けることを願っています。

1
Todd Bleeker