38

在 PowerShell 中,如何测试变量是否包含数值?

目前,我正在尝试这样做,但它似乎总是返回false

add-type -Language CSharpVersion3 @'
    public class Helpers {
        public static bool IsNumeric(object o) {
            return o is byte  || o is short  || o is int  || o is long
                || o is sbyte || o is ushort || o is uint || o is ulong
                || o is float || o is double || o is decimal
                ;
        }
    }
'@

filter isNumeric($InputObject) {
    [Helpers]::IsNumeric($InputObject)
}

PS> 1 | isNumeric
False
4

14 回答 14

54

您可以检查变量是否是这样的数字:$val -is [int]

这适用于数值,但如果数字用引号括起来则不行:

1 -is [int]
True
"1" -is [int]
False
于 2012-06-07T08:16:40.123 回答
32

像这样修改您的过滤器:

filter isNumeric {
    [Helpers]::IsNumeric($_)
}

function使用$input变量来包含管道信息,而使用包含当前管道对象filter的特殊变量。$_

编辑:

对于 powershell 语法方式,您可以只使用过滤器(无添加类型):

filter isNumeric() {
    return $_ -is [byte]  -or $_ -is [int16]  -or $_ -is [int32]  -or $_ -is [int64]  `
       -or $_ -is [sbyte] -or $_ -is [uint16] -or $_ -is [uint32] -or $_ -is [uint64] `
       -or $_ -is [float] -or $_ -is [double] -or $_ -is [decimal]
}
于 2012-06-07T08:20:18.680 回答
32

如果您正在测试一个字符串的数值,那么您可以使用正则表达式和-match比较。否则,克里斯蒂安的回答是类型检查的一个很好的解决方案。

function Is-Numeric ($Value) {
    return $Value -match "^[\d\.]+$"
}

Is-Numeric 1.23
True
Is-Numeric 123
True
Is-Numeric ""
False
Is-Numeric "asdf123"
False
于 2012-06-07T20:46:19.923 回答
29

您可以执行以下操作:

$testvar -match '^[0-9]+$'

或者

$testvar -match '^\d+$'

True如果$testvar是数字则返回。

于 2017-05-10T11:06:53.087 回答
14

如果要检查字符串是否具有数值,请使用以下代码:

$a = "44.4"
$b = "ad"
$rtn = ""
[double]::TryParse($a,[ref]$rtn)
[double]::TryParse($b,[ref]$rtn)

学分在这里

于 2014-12-09T10:17:49.593 回答
11
PS> Add-Type -Assembly Microsoft.VisualBasic
PS> [Microsoft.VisualBasic.Information]::IsNumeric(1.5)
True

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.information.isnumeric.aspx

于 2012-06-07T16:20:44.203 回答
10

-is 和 -as 运算符需要您可以比较的类型。如果您不确定类型可能是什么,请尝试评估内容(部分类型列表):

(Invoke-Expression '1.5').GetType().Name -match 'byte|short|int32|long|sbyte|ushort|uint32|ulong|float|double|decimal'

无论好坏,它也可以对十六进制值起作用(Invoke-Expression '0xA' ...)

于 2012-06-07T08:46:49.853 回答
3
filter isNumeric {
    $_ -is [ValueType]
}

-

1 -is [ValueType]
True
"1" -is [ValueType]
False

-

function isNumeric ($Value) {
    return $Value -is [ValueType]
}

isNumeric 1.23
True
isNumeric 123
True
isNumeric ""
False
isNumeric "asdf123"
False

-

(Invoke-Expression '1.5') -is [ValueType]
于 2017-04-02T10:12:02.843 回答
3
$itisint=$true
try{
 [int]$vartotest
}catch{
 "error converting to int"
 $itisint=$false
}

这更通用,因为这样您也可以测试字符串(例如从文件中读取)是否代表数字。如果您将“123”作为变量中的字符串,则使用 -is [int] 的其他解决方案会导致错误。这也适用于具有较旧 powershell 然后 5.1 的机器

于 2020-05-21T20:30:23.153 回答
2

感谢所有为这个线程做出贡献并帮助我弄清楚如何测试数值的人。我想发布关于如何处理负数的结果,供那些在搜索时也可能找到此线程的人...

注意:由于使用了 Trim(),我的函数需要传递一个字符串。

function IsNumeric($value) {
# This function will test if a string value is numeric
#
# Parameters::
#
#   $value   - String to test
#
   return ($($value.Trim()) -match "^[-]?[0-9.]+$")
}
于 2013-01-10T20:55:58.720 回答
2

我在使用 read-host 进行输入验证时遇到了这个主题。如果我尝试将变量的数据类型指定为 read-host 命令的一部分,并且用户输入了该数据类型以外的内容,则 read-host 会出错。这就是我解决这个问题并确保用户输入我想要的数据类型的方法:

do
    {
    try
        {
        [int]$thing = read-host -prompt "Enter a number or else"
        $GotANumber = $true
        }
    catch
        {
        $GotANumber = $false
        }
    }
until
    ($gotanumber)
于 2017-01-06T18:42:07.500 回答
1
"-123.456e-789" -match "^\-?(\d+\.?\d*)(e\-?\d+)?$|^0x[0-9a-f]+$"

或者

"0xab789" -match "^\-?(\d+\.?\d*)(e\-?\d+)?$|^0x[0-9a-f]+$"

将检查数字(整数、浮点数和十六进制)。

请注意,这不包括逗号/点用作千位分隔符的情况。

于 2020-01-06T21:19:25.627 回答
1

每种数字类型都有自己的值。请参阅 TypeCode 枚举定义: https ://docs.microsoft.com/en-us/dotnet/api/system.typecode?view=netframework-4.8 根据此信息,您所有的数字类型值都在 5 到15. 这意味着,您可以像这样编写条件检查:

$typeValue = $x.getTypeCode().value__
if ($typeValue -ge 5 -and $typeValue -le 15) {"x has a numeric type!"}
于 2020-08-18T10:20:23.880 回答
0

测试一个值是数字还是数字值的字符串表示形式。

function Test-Number 
{
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [ValidatePattern("^[\d\.]+$")]
        $Number
    )

    $Number -is [ValueType] -or [Double]::TryParse($Number,[ref]$null)
}

测试一个值是否为数字。

function Test-Number 
{
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [ValidatePattern("^[\d\.]+$")]
        $Number
    )

    $Number -is [ValueType]
}
于 2017-02-18T02:40:20.183 回答