PowerShell中是否有内置的类似IsNullOrEmpty
函数来检查字符串是空还是空?
到目前为止我找不到它,如果有内置方法,我不想为此编写函数。
你们把这件事做得太难了。 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
您可以使用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
如果它是函数中的参数,您可以使用ValidateNotNullOrEmpty
对其进行验证,如以下示例所示:
Function Test-Something
{
Param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string]$UserName
)
#stuff todo
}
就个人而言,我不接受空格($STR 3)作为"不空"。
当一个只包含空格的变量被传递给参数时,它通常会错误地认为参数值可能不是"$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 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
这里有很多很好的答案;让我用PowerShell惯用的解决方案提供一个务实的总结:
给定一个可能包含$null
或字符串(或任何标量)的变量$str
:
# 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'
注意:如果$str
可以是集合(数组),请使用底部与类型无关的解决方案。
使用仅字符串
-like
运算符隐式将 LHS 强制到字符串,并且由于[string] $null
产生空字符串,因此'' -like ''
和$null -like ''
都产生$true
。同样,基于正则表达式的
-match
/-notmatch
运算符作为仅字符串运算符,将其 LHS 操作数强制为字符串,并且在此转换中$null
被视为''
。S
是一个正则表达式转义序列,它匹配任何非空格字符(它是s
的否定形式)。-match
/-notmatch
默认执行子字符串匹配(并且只返回一个匹配项),因此如果S
匹配,则意味着至少存在一个不是空格字符的字符。
注意事项:
鉴于 PowerShell 的动态类型,您可能事先不知道存储在给定变量中的值的类型。
虽然上述技术适用于可预测的$null
、[string]
实例和其他不可枚举的类型,但可枚举值(字符串除外)可能会产生令人惊讶的结果,因为如果-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]
类型的。
因此,上述与类型无关的等价物- 使用所描述的字符串化规则 - 是:
# Test for $null or '' (empty string) or any stringified value being ''
# Equivalent of: [string]::IsNullOrEmpty($var)
[string] $var -eq ''
# Test for $null or '' or all-whitespace or any stringified value being ''
# Equivalent of: [string]::IsNullOrWhitespace($var)
([string] $var).Trim() -eq ''
我有一个PowerShell脚本,我必须在一台过时的计算机上运行,以至于它没有[String]::IsNullOrWhiteSpace(),所以我编写了自己的脚本。
function IsNullOrWhitespace($str)
{
if ($str)
{
return ($str -replace " ","" -replace "`t","").Length -eq 0
}
else
{
return $TRUE
}
}
# cases
$x = null
$x = ''
$x = ' '
# test
if ($x -and $x.trim()) {'not empty'} else {'empty'}
or
if ([string]::IsNullOrWhiteSpace($x)) {'empty'} else {'not empty'}
解决@KeithHill的答案未涵盖IsNullOrWhitespace
情况的切线缺点,在 PowerShell 7.1 及更高版本中,我们可以使用 null 条件成员运算符优雅地检查字符串是 null 还是空格,而无需首先检查字符串是否不是我们自己$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
为 null 值时,才会调用.Trim()
,否则将返回$null
。
要记住的一件事是,问号?
作为变量名称的一部分是有效的。这就是为什么我们必须在应用条件访问运算符之前首先消除变量名称的歧义,如下所示:${str3}
由于我之前确实提到了三元运算符,并且由于此答案已经以PowerShell 7.1及更高版本为中心,因此您可以使用三元运算符简化上面的代码块,几乎完全删除样板if/then/else
语句:
${str3}?.Trim() ? 'not empty or whitespace' : 'empty or whitespace'
三元运算符是基本条件的简化if/then/else
语句。我不想在这里用细微差别来搅浑水,而是将其解读为"如果唯一的问号?
的左侧为真,请执行?
右侧的内容,或者执行冒号:
之后的内容"。
可以在 PowerShell 文档中阅读有关三元运算符的详细信息。
以纯PowerShell方式实现此目的的另一种方法是执行以下操作:
("" -eq ("{0}" -f $val).Trim())
这将成功计算空值、空字符串和空格。我正在将传递的值格式化为空字符串以处理 null(否则在调用 Trim 时 null 会导致错误)。然后只需使用空字符串评估相等性。我想我仍然更喜欢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())
取决于你想做什么。
可以将条件语句与IsNullOrWhitespace()
和isNullOrEmpty()
静态方法一起使用,以测试空格或 null 值。例如,在插入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-TypeData
向System.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
您可以创建一个将空字符串转换为空值的过滤器,然后只需检查空值。
filter nullif {@($_, $null)[$_ -eq '']}
然后你只需要将你的价值注入其中
('' | nullif) -eq $null
> True
('x' | nullif) -eq $null
> False
一个更简单的 mrthod 是使用正则表达式
$null -match '^$'
> True
'' -match '^$'
> True
'x' -match '^$'
> False
Keith Hill 答案的扩展(以解释空格):
$str = " "
if ($str -and $version.Trim()) { Write-Host "Not Empty" } else { Write-Host "Empty" }
这将为空值、空字符串和带空格的字符串返回"空",为其他所有内容返回"非空"。