我怎么能检查一个字符串是否为空或在PowerShell?

在PowerShell中,是否有一个内置的IsNullOrEmpty-like函数来检查字符串是否为空?

到目前为止我找不到它,如果有内置的方法,我不想为此写一个函数。

768057 次浏览

你可以使用IsNullOrEmpty静态方法:

[string]::IsNullOrEmpty(...)

除了[string]::IsNullOrEmpty之外,为了检查null或空,你可以显式地将一个字符串强制转换为布尔值或布尔表达式:

$string = $null
[bool]$string
if (!$string) { "string is null or empty" }


$string = ''
[bool]$string
if (!$string) { "string is null or empty" }


$string = 'something'
[bool]$string
if ($string) { "string is not null or empty" }

输出:

False
string is null or empty


False
string is null or empty


True
string is not null or empty

你们把事情搞得太复杂了。PowerShell非常优雅地处理了这个问题,例如:

> $str1 = $null
> if ($str1) { 'not empty' } else { 'empty' }
empty


> $str2 = ''
> if ($str2) { 'not empty' } else { 'empty' }
empty


> $str3 = ' '
> if ($str3) { 'not empty' } else { 'empty' }
not empty


> $str4 = 'asdf'
> if ($str4) { 'not empty' } else { 'empty' }
not empty


> if ($str1 -and $str2) { 'neither empty' } else { 'one or both empty' }
one or both empty


> if ($str3 -and $str4) { 'neither empty' } else { 'one or both empty' }
neither empty

如果它是函数中的参数,你可以用ValidateNotNullOrEmpty来验证它,就像你在这个例子中看到的那样:

Function Test-Something
{
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$UserName
)


#stuff todo
}

就我个人而言,我不接受空格($STR3)为“非空”。

当一个只包含空白的变量被传递到一个参数时,通常会错误地认为参数值可能不是'$null',而不是说它可能不是一个空白,一些删除命令可能会删除一个根文件夹而不是子文件夹,如果子文件夹名称是“空白”,所有的原因是在许多情况下不接受包含空白的字符串。

我发现这是最好的方法:

$STR1 = $null
IF ([string]::IsNullOrWhitespace($STR1)){'empty'} else {'not empty'}

$STR2 = ""
IF ([string]::IsNullOrWhitespace($STR2)){'empty'} else {'not empty'}

$STR3 = " "
IF ([string]::IsNullOrWhitespace($STR3)){'empty !! :-)'} else {'not Empty :-('}

空! !: -)

$STR4 = "Nico"
IF ([string]::IsNullOrWhitespace($STR4)){'empty'} else {'not empty'}

非空

我有一个PowerShell脚本,我必须在一台过时的计算机上运行,它没有[String]::IsNullOrWhiteSpace(),所以我自己写了一个。

function IsNullOrWhitespace($str)
{
if ($str)
{
return ($str -replace " ","" -replace "`t","").Length -eq 0
}
else
{
return $TRUE
}
}

在纯PowerShell中完成这一任务的另一种方法是这样做:

("" -eq ("{0}" -f $val).Trim())

此方法成功计算null、空字符串和空白。我正在将传递的值格式化为空字符串以处理null(否则null将在调用Trim时导致错误)。然后用空字符串求相等值。我想我仍然更喜欢IsNullOrWhiteSpace,但如果您正在寻找另一种方法来实现它,那么这个方法也可以。

$val = null
("" -eq ("{0}" -f $val).Trim())
>True
$val = "      "
("" -eq ("{0}" -f $val).Trim())
>True
$val = ""
("" -eq ("{0}" -f $val).Trim())
>True
$val = "not null or empty or whitespace"
("" -eq ("{0}" -f $val).Trim())
>False

在一阵无聊中,我玩了一些,并把它缩短了(尽管更神秘):

!!(("$val").Trim())

!(("$val").Trim())

这取决于你想做什么。

# cases
$x = null
$x = ''
$x = ' '


# test
if ($x -and $x.trim()) {'not empty'} else {'empty'}
or
if ([string]::IsNullOrWhiteSpace($x)) {'empty'} else {'not empty'}

PowerShell 2.0中[string]::IsNullOrWhiteSpace()的替换是string -notmatch "\S"

("\ S" =任何非空白字符)

> $null  -notmatch "\S"
True
> "   "  -notmatch "\S"
True
> " x "  -notmatch "\S"
False

性能非常接近:

> Measure-Command {1..1000000 |% {[string]::IsNullOrWhiteSpace("   ")}}
TotalMilliseconds : 3641.2089


> Measure-Command {1..1000000 |% {"   " -notmatch "\S"}}
TotalMilliseconds : 4040.8453

凯斯·希尔(Keith Hill)的回答(为了解释空白)的延伸:

$str = "     "
if ($str -and $version.Trim()) { Write-Host "Not Empty" } else { Write-Host "Empty" }

返回“空”;对于空字符串,空字符串,有空格的字符串,以及“;Not empty "为了其他的一切。

您可以使用带有IsNullOrWhitespace()isNullOrEmpty()静态方法的条件语句来测试空白或空值。例如,在插入到MySQL数据库之前,我将遍历我将输入的值,并使用条件来避免空值或空白值。

// RowData is iterative, in this case a hashtable,
// $_.values targets the values of the hashtable


```PowerShell
$rowData | ForEach-Object {
if(-not [string]::IsNullOrEmpty($_.values) -and
-not [string]::IsNullOrWhiteSpace($_.values)) {
// Insert logic here to use non-null/whitespace values
}
}

另一种方法是使用Update-TypeDataSystem.String实例中添加2个新的脚本的方法:

Update-TypeData -MemberType ScriptMethod -MemberName IsNullOrEmpty -Value {
return [string]::IsNullOrEmpty($this)
} -TypeName System.String


Update-TypeData -MemberType ScriptMethod -MemberName IsNullOrWhiteSpace -Value {
return [string]::IsNullOrWhiteSpace($this)
} -TypeName System.String


'hello'.IsNullOrEmpty()  # => False
''.IsNullOrEmpty()       # => True
' '.IsNullOrEmpty()      # => False
' '.IsNullOrWhiteSpace() # => True

为了解决@KeithHill的回答没有覆盖IsNullOrWhitespace情况的缺点,在PowerShell 7.1及以后版本中,我们可以使用空条件成员运算符优雅地检查字符串是否为空或空白,而不需要首先检查字符串是否不是$null,同时避免使用[string]::IsNullOrWhitespace(string)

如果你启用了PSNullConditionalOperators实验特性,你也可以在PowerShell 7.0中这样做:

Enable-ExperimentalFeature -Name PSNullConditionalOperators

使用Keith回答中的$str3例子(为了清晰起见,假装三元操作符在7.0之后就不存在了):

$str3 = ' '
if ( ${str3}?.Trim() ) {
'not empty or whitespace'
} else {
'empty or whitespace'
}
empty or whitespace

只有当$str3是非空值时才会调用.Trim(),否则将返回$null


要记住的一点是,问号?作为变量名的一部分是有效的。这就是为什么我们必须在应用条件访问操作符之前消除变量名的歧义:${str3}


因为我之前提到过三元操作符,而且因为这个答案已经围绕PowerShell 7.1及以后的版本展开,你可以通过使用三元操作符来简化上面的代码块,几乎完全删除样板语句if/then/else:

${str3}?.Trim() ? 'not empty or whitespace' : 'empty or whitespace'

三元运算符是用于基本条件的简化的if/then/else语句。我不想用它周围的细微差别把水弄得太浑,但是把它理解为“如果孤独的问号?的左边是正确的,执行?右边的内容,或者执行冒号# eyz3后面的内容”。

您可以在PowerShell文档中阅读关于三元操作符的更多信息。

这里有很多很好的答案;让我提供一个务实的总结PowerShell-idiomatic解决方案:

给定一个变量$str,它可能包含$null字符串(或任何标量):

# Test for $null or '' (empty string).
# Equivalent of: [string]::IsNullOrEmpty($str)
$str -like ''


# Test for $null or '' or all-whitespace.
# Equivalent of: [string]::IsNullOrWhitespace($str)
$str -notmatch '\S'
  • 使用仅限字符串的-like操作符隐式强制LHS为字符串,由于[string] $null产生空字符串,'' -like ''$null -like ''都会产生$true

  • 类似地,基于# eyz4的# eyz0 / # eyz1操作符与string-only操作符一样,将它们的LHS操作数强制转换为字符串,在此转换中,$null被视为''

    • \S是一个正则表达式转义序列,它匹配任何# eyz2 -空白字符(它是\s的否定形式)。

    • -match / -notmatch默认执行子字符串匹配(并且只返回一个匹配),因此如果\S匹配,则意味着至少有一个字符不是空白字符。


# EYZ0:

鉴于PowerShell的动态类型,您可能无法提前知道存储在给定变量中的值的类型。

虽然上述技术可预测地适用于$null[string]实例以及不可数enumerable值(字符串除外)可能会产生令人惊讶的结果的其他类型,因为如果-like-notmatch的LHS是可枚举的(松散地说:集合),则该操作应用于每个元素,而不是返回单个布尔值,而是返回匹配元素的子数组

在条件上下文中,将数组强制转换为布尔值的方式有点违反直觉;如果数组只有一个元素,则该元素本身被强制转换为布尔值;对于两个或更多元素,数组总是被强制转换为$true,无论元素值如何——请参阅这个答案的底部部分。例如:

# -> 'why?', because @('', '') -like '' yields @('', ''), which
# - due to being a 2-element array - is $true
$var = @('', '')
if ($var -like '') { 'why?' }

如果您将非字符串枚举LHS强制转换为[string], PowerShell通过空格连接它的(字符串化的)元素来对它进行字符串化。 当您调用[string]::IsNullOrEmpty()[string]::IsNullOrWhiteSpace()时,隐式地也会发生这种情况,因为它们的参数是[string]-typed

因此,类型不可知的等价物 -使用描述的字符串化规则-是:

# Test for $null or '' (empty string) or any stringified value being ''
# Equivalent of: [string]::IsNullOrEmpty($var)
[string] $var -like ''


# Test for $null or '' or all-whitespace or any stringified value being ''
# Equivalent of: [string]::IsNullOrWhitespace($var)
[string] $var -notmatch '\S'

您可以创建一个过滤器,将空字符串转换为null,然后只需检查是否为null。

filter nullif {@($_, $null)[$_ -eq '']}

然后你只需要将你的价值注入其中

('' | nullif) -eq $null
> True
('x' | nullif) -eq $null
> False

一个更简单的方法是使用正则表达式

$null -match '^$'
> True
'' -match '^$'
> True
'x' -match '^$'
> False