ChatGPT解决这个技术问题 Extra ChatGPT

如何在 PowerShell 中检查字符串是否为空或为空?

在 PowerShell 中是否有一个类似 IsNullOrEmpty 的内置函数来检查字符串是否为空或空?

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

好吧,您使用的是 .NET,所以不能调用 String.IsNullOrEmpty 吗?
@TooTone PowerShell 可以访问并且有时依赖 .NET 进行某些函数调用,正如这里的几个答案所示。删除标签会使这些答案无效,这使其成为不允许的编辑。
@TylerH 对不起,我没有意识到。感谢您的更正和评论。

a
anon

你们这太难了。 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

@pencilCake 是的,我在说什么,上面的例子展示了它的实际效果。测试不会检查的是 IsNullOrWhitespace()。
@VertigoRay 请参阅我上面的第一条评论,我建议在该场景中使用 IsNullOrWhitespace()。但是在使用 PowerShell 编写脚本 11 年后,我发现我需要很少进行字符串测试。 :-)
如果变量类型不受限制,这在 PowershellJavascript 中都是危险的做法。考虑一下:$str1=$false$str1=@(0)
“KeithHill。抱歉这仍然不安全,因为你的意图不明确。当你使用 [string]::IsNullOrEmpty 时,你绝对清楚。IMO,Powershell 是一个最奇怪的创造 - 大多数时候它过于丰富,但仍然缺少必需品。-isNullOrEmpty 谓词就是其中之一...
@dmitry 通过了解您想要的东西来解决这个问题。而且通常“真实”或“虚假”就足够了,你可以在有限的上下文中挥手甩掉很多其他的事情。一个字符串数组可以包含0,但如果它不是supposed,则不一定是您的方法需要关心的工作。 (而且,潜在的错误可能已经严重到足以证明额外防御是合理的。)
Д
ДМИТРИЙ МАЛИКОВ

您可以使用 IsNullOrEmpty 静态方法:

[string]::IsNullOrEmpty(...)

我更喜欢这种方式,因为不管你的 Powerhsell 知识如何,它的作用都很明显——这对非 Powershell 程序员来说是有意义的。
我想你可以这样做!$var
使用 PowerShell 需要注意的一件事是,传递给命令行开关或函数的空字符串不会保持为空。它们被转换为空字符串。请参阅 connect.microsoft.com/PowerShell/feedback/details/861093/… 处的 Microsoft Connect 错误。
考虑 [String]::IsNullOrWhiteSpace(...) 来验证空格。
@ShayLevy 小心使用 !。这仅适用于较新版本的 PowerShell。 !-not 的别名
R
Roman Kuzmin

除了 [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

好点。 If 子句在内部将括号内的所有内容转换为单个布尔值,这意味着 if($string){Things to do for non-empty-nor-null}if(!$string){Things to do for empty-or-null} 无需显式转换 [bool] 就足够了。
这些隐式转换是最危险的。您需要确保您具有确切的字符串类型。考虑 $string=@(0) - 很有可能发生......
R
Rubanov

如果它是函数中的参数,您可以使用 ValidateNotNullOrEmpty 对其进行验证,如下例所示:

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

    #stuff todo
}

这是迄今为止更好的方法。虽然,这并不是所问问题的完全解决方案。
N
Nico van der Stok

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

当一个只包含空格的变量被传递给一个参数时,它通常会出错,参数值可能不是'$null',而不是说它可能不是一个空格,一些删除命令可能会删除一个根文件夹而不是一个subfolder 如果子文件夹名称是“空格”,那么在许多情况下,所有理由不接受包含空格的字符串。

我发现这是实现它的最佳方法:

$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'}

不是空的


.Net 有 String::IsNullOrEmpty 用于您的目的。
N
Nikolay Polyagoshko

[string]::IsNullOrWhiteSpace() 的 PowerShell 2.0 替代品是 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

m
mhenry1384

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

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

您不能使用 .Trim() 而不是列出空格类型吗?所以它会是$str.Trim().Length -eq 0
S
Skatterbrainz
# cases
$x = null
$x = ''
$x = ' '

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

P
Peter Mortensen

以纯 PowerShell 方式完成此操作的另一种方法是执行以下操作:

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

这会成功评估 null、空字符串和空格。我将传递的值格式化为空字符串以处理 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())

取决于你想要做什么。


m
mklement0

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

给定一个可能包含 $null 或字符串的变量 $str

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

# Test for $null or '' or all-whitespace.
# Equivalent of: [string]::IsNullOrWhitespace($str)
$str -notmatch '\S'  

使用 -not 运算符利用了 PowerShell 的隐式到布尔转换逻辑: -not 强制将字符串操作数转换为布尔值,空字符串被视为 $false,而任何非空字符串 - 无论其值如何 -是 $true;同样,$null 总是转换为 $false。有关 PowerShell 到布尔转换的一般概述,请参阅此答案的底部部分。

有关 PowerShell 到布尔转换的一般概述,请参阅此答案的底部部分。

基于正则表达式的 -match / -notmatch 运算符,作为纯字符串运算符,将其 LHS 操作数强制转换为字符串,并且 $null 在此转换中被视为 ''。 \S 是匹配任何非空白字符的正则表达式转义序列(它是 \s 的否定形式)。 -match / -notmatch 默认情况下执行子字符串匹配(并且只返回一个匹配项),因此如果 \S 匹配,则暗示至少存在一个不是空白字符的字符。

\S 是匹配任何非空白字符的正则表达式转义序列(它是 \s 的否定形式)。

-match / -notmatch 默认情况下执行子字符串匹配(并且只返回一个匹配项),因此如果 \S 匹配,则暗示至少存在一个不是空白字符的字符。


S
Santiago Squarzon

另一种使用 Update-TypeData 将 2 个新 Script Methods 添加到 System.String 实例的替代方法:

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

B
Bender

解决了 @KeithHill's answer 不涵盖 IsNullOrWhitespace 情况的切向缺点,在 PowerShell 7.1 及更高版本中,我们可以使用 null-conditional member operator 优雅地检查字符串是否为空或空格,而无需先检查该字符串不是我们自己的 $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}

由于我之前确实提到了三元运算符,and 因为这个答案已经围绕 PowerShell 7.1 及更高版本,您可以通过使用三元运算符来简化上面的代码块,几乎完全删除样板 if/then/else 语句:

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

ternary operator 是基本条件的简化 if/then/else 语句。我不想在这里用细微差别把水弄得太多,但把它读作“如果 lone 问号 ? 的左侧是真的,执行上面的内容? 的右侧,否则执行冒号 :" 之后的内容。

您可以在 PowerShell documentation 中阅读有关三元运算符的更多信息。


S
Steve Friedl

请注意,"if ($str)""IsNullOrEmpty" 测试并非在所有情况下都同样有效:$str=0 的赋值对两者都产生错误,并且根据预期的程序语义,这可能会产生意外。


$str=0 不是一个好的编码习惯。 $str='0' 将毫无疑问地确定 IsNullOrEmpty 的预期结果。
这是不正确的。 $str=0 分配与 $str=1$str=1000 相同的整数值。如果您需要将纯数字字符串分配给变量,请使用 [string]'0'"0" 将整数转换为字符串,或者在声明时强定义变量的类型(在这种情况下,转换将在赋值时发生) .请注意,这些示例中的 0 可以替换为任何整数值
Z
Zodman

基思希尔的答案的扩展(考虑空格):

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

对于空值、空字符串和带有空格的字符串,这将返回“Empty”,而对于其他所有内容,则返回“Not Empty”。


T
Toni

您可以使用带有 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
    }
}

K
KERR

有点相关的 hack - 您可以排除空值(例如 Excel 习惯在复制到 PowerShell 时包含一个额外的空单元格),如下所示:

get-clipboard | ? {$_}

什么是 get-clipboard,它与这个问题有什么关系?如果这是我认为的那样,OP 并没有表示他们正在尝试检查 Windows 剪贴板存储中第一项的值(在这种情况下,这不会回答问题)。