Вопрос по powershell – Как в PowerShell проверить, содержит ли переменная числовое значение?

22

Как в 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

Ваш Ответ

11   ответов
21

вы можете использовать регулярное выражение и-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
Я оставлю это как упражнение для читателя. :) Я просто хотел добавить это для людей, которые могут наткнуться на вопрос, ищущий проверку числовых строковых значений.
Я не тестирую строку, я тестирую тип. Но игнорируя это на данный момент, как насчет отрицательных значений? А как насчет экспоненциальных значений (3.24643e4)? Да, я знаю, что я расщепляю волосы! Damian Powell
"1.2.3" -match "^[\d\.]+$" - & GT; Правда."^(\d+|\.\d+|\d+\.\d+)$" позволит только один десятичный разделитель. Возвращает true для "1", ".1", "1.1" и ложно для "1.", "1.1.1", "."
Молодец @silent__thought, я искал именно это.
11

Вы можете сделать что-то вроде:

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

или же

$testvar -match '^\d+$'

Возвращает & quot; True & quot; если $ testvar это число

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]
}
$n=0; [Double]::TryParse('1e2', [ref]$n) будет анализировать его как строковое представление числа, но ваши функции потерпят неудачу. То же самое с отрицательными числами.
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]
PS & GT; [System.Reflection.BindingFlags] :: CreateInstance -is [valuetype] (True)
PS & GT; [Символ] & Quot; & Quot; -is [valuetype] (True)
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)
5

имеет ли строка числовое значение, используйте этот код:

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

Кредиты идутВот

32

$val -is [int]

Это будет работать для числовых значений, но не в том случае, если число заключено в кавычки:

1 -is [int]
True
"1" -is [int]
False
@ Кристиан, ты прав. Я только думал о случае в вопросе.
@ CB, потому что1.5 это не целое число, это двойное ...1.5 -is [double] оценивает как истинное
как насчет оценки числа, как 1,5? Твой путь вернуть Ложь ..
9
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

Я думал, что это было довольно аккуратно, пока я не понял, что он вернет true для строки, которая была числовой, такой как"1.23" что не то, что я хочу. Я хочу знать, является ли тип фактического объекта числовым типом, а не может ли он быть приведен к числовому типу. Спасибо за полезный совет, хотя, я вижу, где это будет очень удобно. Damian Powell
22

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

function использует$input переменная, чтобы содержать информацию о конвейере, тогда какfilter использует специальную переменную$_ который содержит текущий объект конвейера.

Редактировать:

Для синтаксического подхода powershell вы можете использовать только фильтр (без 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]
}
@DamianPowell Всегда рад помочь, в прошлом у меня была похожая проблема с синтаксисом фильтра;)
Я думаю, что собственный путь PowerShell - это путь, по которому я буду идти. Спасибо, Кристиан. Damian Powell
$_ -is [int] работает тоже, чтобы проверить на int
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.]+$")
}
Это вернет true для номеров версий, таких как «9.3.4», вы будете лучше обслуживаться регулярным выражением типа^[-+]?([0-9]*\.[0-9]+|[0-9]+\.?)$ который подтвердит, у вас есть только дополнительный плюс / минус; цифры и один дополнительный десятичный знак.
8

с которым вы можете сравнивать. Если вы не уверены, какой тип может быть, попробуйте оценить содержимое (неполный список типов):

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

Хорошо это или плохо, он может работать и с шестнадцатеричными значениями (Invoke-Expression '0xA' ...)

Это аккуратное решение. Для контекста мне нужно использовать его, хотя,Invoke-Expression может быть довольно хитроумно! Damian Powell

Похожие вопросы