2012-06-07 2 views
19

Dans PowerShell, comment puis-je tester si une variable contient une valeur numérique?Dans PowerShell, comment puis-je tester si une variable contient une valeur numérique?

Actuellement, j'essaye de le faire comme ceci, mais il semble toujours retourner 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 

Répondre

20

Modifier votre filtrer comme ceci:

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

function utilise le $input variable pour contenir des informations de pipeline alors que le filter utilise la variable spéciale $_ qui contient l'objet de pipeline en cours.

Edit:

Pour une façon de syntaxe powershell vous pouvez utiliser juste un filtre (w/o add-type):

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] 
} 
+0

@DamianPowell Toujours heureux d'aider, dans le passé, j'ai eu un problème similaire avec la syntaxe de filtre; –

+0

Je pense que la route natif PowerShell est la façon dont je vais aller. Merci, @ Christian. –

25

Vous pouvez vérifier si la variable est un nombre comme ceci: $val -is [int]

Cela fonctionne pour les valeurs numériques, mais pas si le nombre est entre guillemets doubles:

1 -is [int] 
True 
"1" -is [int] 
False 
+3

ce que sur l'évaluation d'un nombre équivalent de 1,5 ?? Votre chemin retour Faux .. –

+0

@ Christian vous avez raison. Je pensais seulement à l'affaire dans la question. – tophatsteve

+0

@CB c'est parce que '1.5' n'est pas un entier, c'est un double ...' 1.5 -is [double] 'évalue à vrai –

8

-is et -as opérateurs requiert un type que vous pouvez comparer à . Si vous n'êtes pas sûr de ce type pourrait être, essayer d'évaluer le contenu (liste de type partiel):

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

Bon ou mauvais, il peut travailler contre les valeurs hexagonales et (Invoke-Expression « 0xA ». ..)

+0

C'est une solution soignée. Pour le contexte, j'ai besoin de l'utiliser, 'Invoke-Expression' pourrait être assez douteux! –

7
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

+0

Je pensais que c'était assez soigné jusqu'à ce que je me rende compte que cela reviendrait vrai pour une chaîne qui était numérique, comme '" 1.23 "' ce qui n'est pas ce que je veux. Je veux savoir si le type de l'objet réel est un type numérique, et non si oui ou non il peut être contraint à un type numérique. Merci pour un conseil utile cependant, je peux voir où cela sera très utile. –

18

Si vous testez une chaîne pour une valeur numérique, vous pouvez utiliser l'expression régulière et la comparaison -match. Sinon, la réponse de Christian est une bonne solution pour la vérification de type.

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

Is-Numeric 1.23 
True 
Is-Numeric 123 
True 
Is-Numeric "" 
False 
Is-Numeric "asdf123" 
False 
+0

Je ne teste pas une chaîne, je teste un type. Mais ignorant cela pour le moment, qu'en est-il des valeurs négatives? Et qu'en est-il des valeurs exponentielles (3.24643e4)? Oui, je sais, je suis en train de couper les cheveux! –

+0

Je vais laisser cela comme un exercice pour le lecteur. :) Je voulais juste ajouter ceci pour les personnes qui pourraient trébucher sur la question à la recherche de valeurs de chaînes numériques. – joshuapoehls

+1

Bien fait @silent__thought, je cherchais exactement cela. –

3

Merci à tous ceux qui ont contribué à ce sujet et qui m'ont aidé à comprendre comment tester les valeurs numériques. Je voulais publier mes résultats pour savoir comment gérer les nombres négatifs, pour ceux qui peuvent également trouver ce fil lors de la recherche ...

Note: Ma fonction nécessite une chaîne de caractères, en raison de l'utilisation de 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.]+$") 
} 
+2

Cela retournera vrai pour les numéros de version comme "9.3.4", vous seriez mieux servi par une regex comme '^ [- +]? ([0-9] * \. [0-9] + | [0 -9] + \.?) $ 'Qui validera vous avez seulement un plus/moins optionnel; nombres et un seul point décimal optionnel. –

3

Si vous voulez vérifier si une chaîne a une valeur numérique, utilisez ce code:

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

Crédits vont here

1

Je suis tombé sur ce sujet tout en travaillant sur la validation d'entrée avec lecture -hôte. Si j'essayais de spécifier le type de données pour la variable dans le cadre de la commande read-host et que l'utilisateur saisissait autre chose que ce type de données, read-host ferait une erreur.Voilà comment je suis arrivé autour de cela et veillé à ce que l'utilisateur entre le type de données que je voulais:

do 
    { 
    try 
     { 
     [int]$thing = read-host -prompt "Enter a number or else" 
     $GotANumber = $true 
     } 
    catch 
     { 
     $GotANumber = $false 
     } 
    } 
until 
    ($gotanumber) 
0

Test si une valeur est numérique ou une représentation de chaîne d'une valeur numérique.

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

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

Tester si une valeur est numérique.

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

    $Number -is [ValueType] 
} 
+0

'$ n = 0; [Double] :: TryParse ('1e2', [ref] $ n) 'l'analysera comme une représentation sous forme de chaîne d'un nombre, mais vos fonctions l'échoueront. Pareil avec des nombres négatifs. – TessellatingHeckler

0
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] 
6

Vous pouvez faire quelque chose comme:

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

ou

$testvar -match '^\d+$' 

Retours "True" si testvar de $ est un nombre

Questions connexes