在PowerShell中检查字符串是否包含数值?

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

我想检查字符串是否包含数值。我有这个代码:

$string = "some string that contains 123456     in the middle"
$substring = $string.substring(27,9).Trim()

我有 $substring 它将包含“123456”,我在这里找到了这个 IsNumeric 函数: 在 PowerShell 中,如何测试变量是否包含数值?

问题是,当我从 $string 中提取它时,它的行为就像字符串类型,而 IsNumeric 返回 false,因为它将它与所有数字类型进行比较。即使它包含一个数字,IsNumeric 的输出也将是 false。

有没有更好的方法来检查字符串是否包含数值?

powershell numeric
8个回答
28
投票

可以使用正则表达式匹配来测试一下:

if($substring -match "^\d+$")
{
   # Do something
}

这应该适用于仅包含数字(即正整数)的任何字符串。 如果您想包含负整数,请将模式更改为

^-?\d+$


18
投票

检查给定字符串是否可以转换为数字的正确方法:

[string]$InString = "123456"
[Int32]$OutNumber = $null

if ([Int32]::TryParse($InString,[ref]$OutNumber)){
    Write-Host "Valid Number"
    $OutNumber
} else {
    Write-Host "Invalid Number"
    #error code here
}

然后

$OutNumber
将包含数字作为数字类型。


10
投票

在正则表达式中 \d 是对数字的检查

\d* 检查 0 到无限数字

\d?检查 0 到 1 位数字

\d{0,5} 检查 0 到 5 位数字

\d+ 检查 1 到无限数字

^ 是一行的开头

$ 是行尾

所以

^\d+$ 将检查从行首到行尾的 1 个或多个数字,并且仅检查数字。任何其他符号都会破坏从头到尾的连接并且不会被发现。


6
投票

使用

-as
type_operator 可能是最强大的 shell 方式。它将返回数字,如果无法转换则返回
$null
。为了使示例尽可能简短,我使用
int
但这也适用于
float
double
。例如:

"0" -as [int]

如果出于某种原因您only想检查字符串是否包含数字数据,那么您可以简单地通过

$null
针对
($null -ne ("0" -as [int]))

进行测试

但是,如果可能的话,您更有可能想要使用转换后的值,这很容易通过将结果分配给变量然后检查

$null

来完成
$myNum = "0" -as [int]
if ($myNum -eq $null) {
    #is not numeric
} else {
    #is numeric
}

使用异常作为程序控制是一种非常糟糕的做法,并且可能保证您会看到性能的提高。

我还没有测试过这个断言,但我认为您很可能也会看到发布的正则表达式方法的性能有所提高,而且还有一个方便的数字。你可以使用带有分组的正则表达式来实现同样的事情,但还没有人发布:

"0" -match "(?<num>\d*)"
$Matches.num

加上你仍然实际上已经进行了转换:

$Matches.num.GetType()
([Int32]$Matches.num).GetType()

4
投票

使用.NET框架的传统方式:

if( [Microsoft.VisualBasic.Information]::IsNumeric($myString) ) {
  # do something
}

0
投票

使用错误

它也接受小数。

[string]$myString = "12.3456"
try{
    [int]$res=[int]1*$myString
    Write-Host "Valid Number"
}catch{
    Write-Host "Invalid Number"
}

0
投票

这就是我测试字符串是否为数字的方法。 它考虑了数字文字格式,并且不需要转换为表示数字的几种数据类型中的任何一种。

function Test-StringIsNumber
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        #[System.String[]]$InputObject,
        $InputObject,

        [switch]$PassThru
    )

    process
    {
        foreach ($strValue in $InputObject)
        {
            $result = $false
            $output = $strValue

            try
            {
                # Check Get-Command first to make sure that Invoke-Expression doesn't actually run something.
                # Even if a cmdlet or function has a name that's a numeric literal (e.g. function 5GB {throw "!"}), the literal will be parsed first.
                if ($null -eq (Get-Command -Name $strValue -ErrorAction Ignore))
                {
                    $output = Invoke-Expression -Command $strValue -ErrorAction Stop

                    # $strValue is a number or uses numeric literal formatting.
                    $result = $true
                }
            } catch {}

            $outputObj = $result

            if ($PassThru)
            {
                $objType = [System.Type]::GetType($output.GetType().FullName)

                $obj = [pscustomobject] @{
                    InputObject = $strValue
                    ExpandedValue = $output
                    Type = $objType
                    IsNumber = $result
                }
                $outputObj = $obj
            }
            Write-Output $outputObj
        }
    } #process
} #function Test-StringIsNumber



结果:

PS C:\> Test-StringIsNumber '0xf'
True

PS C:\> Test-StringIsNumber '0xh'
False

PS C:\> Test-StringIsNumber '500.9L'
True

PS C:\> Test-StringIsNumber '100gbL'
False

PS C:\> Test-StringIsNumber 1.79769313486232E+11 -PassThru

         InputObject    ExpandedValue Type          IsNumber
         -----------    ------------- ----          --------
1.79769313486232E+11 179769313486.232 System.Double     True

PS C:\> Test-StringIsNumber '-0xbadf00d' -PassThru

InputObject ExpandedValue Type         IsNumber
----------- ------------- ----         --------
-0xbadf00d     -195948557 System.Int32     True

PS C:\> Test-StringIsNumber '-0xg00df00d' -PassThru

InputObject ExpandedValue Type          IsNumber
----------- ------------- ----          --------
-0xg00df00d -0xg00df00d   System.String    False

-1
投票

使用 -match '\d'

string = "some string that contains 123456     in the middle"
$substring = $string.substring(27,9).Trim()
$substring -match '\d'
© www.soinside.com 2019 - 2024. All rights reserved.