14

I want to check if a string contains a numeric value. I have this code :

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

I have $substring which will be containing "123456" and I found this IsNumeric function here : In PowerShell, how can I test if a variable holds a numeric value?

The thing is that this when I'm extracting it from $string it acts like string type and IsNumeric returns false since it's comparing it to the all numeric types. and even tough it will contain a number the output of IsNumeric will be false.

Is there a better way to check if string contains numeric values?

Marked One
  • 294
  • 2
  • 3
  • 13

7 Answers7

26

You can use a regular expression match to test it:

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

This should work for any string which contains only digits (i.e. is a positive integer). Change the pattern to ^-?\d+$ if you want to include negative integers.

boxdog
  • 7,894
  • 2
  • 18
  • 27
16

The correct way to check if a given string can be turned into a number:

[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
}

then $OutNumber will contain the number as a numeric type.

colsw
  • 3,216
  • 1
  • 14
  • 28
10

In regex \d is the check for digits

\d* checks for 0 to infinite digits

\d? Checks for 0 to 1 digit

\d{0,5} checks for 0 to 5 digits

\d+ checks for 1 to infinite digits

^ is the beggining of a line

$ is the end of a line

So

^\d+$ will check for 1 or more digits from the beginning to the end of the line and only digits. Any other symbol will break the connection from beginning to end and not be found.

Robert Cotterman
  • 2,213
  • 2
  • 10
  • 19
4

The traditional way using the .NET framework:

if( [Microsoft.VisualBasic.Information]::IsNumeric($myString) ) {
  # do something
}
f6a4
  • 1,684
  • 1
  • 10
  • 13
  • Add-Type -AssemblyName Microsoft.VisualBasic; Add-Type -AssemblyName 'Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'; – Garric Nov 14 '21 at 18:14
2

Using the -as type_operator is probably the most powershell way. It will return the number, or $null if it was not possible to convert. To keep the examples as short as possible I am using int but this will work for float and double as well. For example:

"0" -as [int]

If for some reason you only wanted to check if the string contains numeric data then you could simply test this against $null via ($null -ne ("0" -as [int]))

But it's probably far more likely that you will want to use the value once converted, if possible, which is easily done by just assigning the result to a variable then checking against $null:

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

Using exceptions as program control is a very bad practice, and likely a guarantee that you will see a performance increase with this over that.

I haven't tested this assertion, but I think it is very likely you will also see a performance increase over the regex method posted as well, with the bonus of also having the number handy. You could use a regex with grouping to achieve the same thing, but nobody has posted that yet:

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

Plus you still have actually do the conversion:

$Matches.num.GetType()
([Int32]$Matches.num).GetType()
DreadedEntity
  • 133
  • 1
  • 7
0

using error

It's accepts decimal numbers too.

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

use -match '\d'

string = "some string that contains 123456     in the middle"
$substring = $string.substring(27,9).Trim()
$substring -match '\d'
Simon B
  • 210
  • 1
  • 5
  • It actually returns true for every type of substring that I've tried. Even with letters and numbers mixed together – Marked One Jul 04 '18 at 10:49
  • 2
    @MarkedOne the regex here should have been `^\d+$` to say 'only numbers' rather than just 'contains at least one number'. – colsw Jul 04 '18 at 11:08
  • "Is there a better way to check if string contains numeric value?" I read this as a string may contain a numeric value not only numeric values :) – Simon B Jul 04 '18 at 11:26