I am using PowerShell 7.1.4 and I wanna check if a string can be converted to a number.
Something like:
$age = Read-Host "age"
if(![int]$age) {
Write-Host "$age is not a number"
}
I came from JavaScript so don't mind the "!" if its wrong, and I just started learning PowerShell.
CodePudding user response:
You can use $age -as [int]
, which returns $null
if conversion to the RHS type isn't possible, so that $null -eq ($age -as [int])
is only $true
if the conversion is not possible (see -as
, the conditional type conversion operator):
if ($null -eq ($age -as [int])) { Write-Host "$age is NOT a number." }
If you also want to save the converted value, you can take advantage of PowerShell's ability to use assignments as expressions:
if ($null -eq ($ageNumber = $age -as [int])) { Write-Host "$age is NOT a number." }
Caveat: -as
and [int]
casts convert the empty or blank (all-whitespace) strings (as well as $null
) to 0
. (Try '' -as [int]
, ' ' -as [int]
, and $null -as [int]
).
To avoid that:
- either: use the .NET approach shown in the next section
- or: add an additional check to detect these cases:
if ('' -eq $age.Trim() -or $null -eq ($age -as [int])) { Write-Host "$age is NOT a number." }
A less PowerShell-idiomatic, but stricter alternative would be to use the [int]::TryParse()
.NET method:
if (-not [int]::TryParse($age, [ref] $null)) { Write-Host "$age is NOT a number." }
If you also want to save the converted value, initialize an output variable and pass it in lieu of $null
:
$ageNumber = $null # Initialize the output variable (type doesn't matter).
if (-not [int]::TryParse($age, [ref] $ageNumber)) { Write-Host "$age is NOT a number." }
As implied above, this method does not recognize empty and blank strings as an integer.
As for what you tried:
!
is a valid PowerShell operator; its alias is -not
PowerShell implicitly converts its operand to a Boolean (
[bool]
), so a caveat with respect to integers is that! 0
is also$true
, even though0
is a valid integer.See the bottom section of this answer for an overview of PowerShell's implicit to-Boolean conversions.
The problem is that an [int]
cast causes a statement-terminating error when its operand can not be converted to the specified type. The use of the -as
operator avoids this problem.
For the sake of completeness: it is possible - though not advisable here - to use a try { ... } catch { ... }
statement enclosed in $()
, the subexpression operator, to catch the error:
if ($null -eq $(try { [int] $age } catch {})) { Write-Host "$age is NOT a number." }