如何在PowerShell中检查字符串是空还是空?

pen*_*ake 375 .net string powershell null

IsNullOrEmpty在PowerShell中是否有内置函数来检查字符串是空还是空?

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

Kei*_*ill 559

你们这样做太难了.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
Run Code Online (Sandbox Code Playgroud)

  • @pencilCake是的,我所说的和上面的例子显示了它的实际效果.测试不会检查的是IsNullOrWhitespace(). (29认同)
  • 从脚本角度来看,我更赞同这个解决方案.一如既往,Keith Hill拥有正确的解决方案!谢谢. (3认同)
  • 如果变量类型不受限制,这在 _Powershell_ 和 _Javascript_ 中都是危险的做法。考虑一下:`$str1=$false` 或 `$str1=@(0)` (3认同)
  • 比 [string]::IsNullOrEmpty(...) 干净得多 (2认同)
  • 你说优雅,但出于某种原因,这感觉就像JS. (2认同)
  • @VertigoRay看到我上面的第一条评论,我建议在那个场景中使用`IsNullOrWhitespace()`.但是在使用PowerShell编写11年脚本后,我发现我很少需要字符串测试*.:-) (2认同)
  • "KeithHill.对不起,这仍然不安全,因为你的意图不明确.当你使用[string] :: IsNullOrEmpty时,你绝对清楚.IMO,Powershell是一个最奇怪的创造 - 大多数时候它过于丰富,但仍然缺少必需品.-isNullOrEmpty谓词就是其中之一...... (2认同)
  • @Lee 首先,您需要了解您想要的是什么。不这样做是所有错误的开始。一个简单的例子 - 通过删除空值来减少数组。如果您假设一个隐式布尔值(如 Keith Hill 建议的那样),您还可以过滤掉非空的、具有 0、null 或空字符串或布尔值 false 的值。 (2认同)
  • @dmitry 通过理解你想要什么来解决这个问题。通常“真实”或“虚假”就足够了,你可以在有限的上下文中放弃很多其他东西。字符串数组_可能_包含“0”,但如果_不应该_包含“0”,则_你的方法_不一定需要关心它。(而且,潜在的错误可能很严重,以至于需要采取额外的防御措施。) (2认同)

Sha*_*evy 426

您可以使用IsNullOrEmpty静态方法:

[string]::IsNullOrEmpty(...)
Run Code Online (Sandbox Code Playgroud)

  • 考虑[String] :: IsNullOrWhiteSpace(...)来验证空格. (24认同)
  • 我想你可以做到!$ var (16认同)
  • 使用PowerShell需要注意的一点是,传递给命令行开关或函数的空字符串不会保持为空.它们被转换为空字符串.请参阅https://connect.microsoft.com/PowerShell/feedback/details/861093/nullstring-value-is-not-preserved-when-passed-to-functions上的Microsoft Connect错误. (4认同)
  • 我更喜欢这种方式,因为无论你的Powerhsell知识如何,它显然是什么 - 这对非Powershell程序员来说是有意义的. (2认同)
  • @ShayLevy小心`!`。仅在较新版本的PowerShell中有效。`!`是`-not`的别名 (2认同)

Rom*_*min 38

除了[string]::IsNullOrEmpty为了检查null或empty之外,您还可以显式地或在布尔表达式中将字符串强制转换为布尔值:

$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" }
Run Code Online (Sandbox Code Playgroud)

输出:

False
string is null or empty

False
string is null or empty

True
string is not null or empty
Run Code Online (Sandbox Code Playgroud)

  • 好点.`if`子句在内部将括号内的所有内容转换为单个布尔值,这意味着`if($ string){要做的事情为非空-nor-null}`或`if(!$ string){要做的事情为空 - 或者null}`没有显式转换`[bool]`就足够了. (2认同)

Rub*_*nov 18

如果它是函数中的参数,则ValidateNotNullOrEmpty可以使用此示例中的参数进行验证:

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

    #stuff todo
}
Run Code Online (Sandbox Code Playgroud)


mkl*_*nt0 15

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

$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'  
Run Code Online (Sandbox Code Playgroud)

注意:如果$str可以是集合(数组),请使用底部与类型无关的解决方案。

  • 使用仅字符串-like运算符隐式将 LHS 强制转换为string,并且由于[string] $null产生空字符串,因此'' -like ''$null -like ''yield $true

  • 类似地,基于正则表达式-match/-notmatch运算符作为仅字符串运算符,将其 LHS 操作数强制为字符串,并像在此转换中$null一样进行处理''

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

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


警告

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

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

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

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

如果将非字符串可枚举 LHS 转换为[string],PowerShell 会通过空格连接其(字符串化)元素对其进行字符串化。这也是您调用or时隐式发生的情况,因为它们的参数是-typed 的。[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 ''
Run Code Online (Sandbox Code Playgroud)


Nic*_*tok 10

就个人而言,我不接受空格($ STR3)为"非空".

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

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

$STR1 = $null
IF ([string]::IsNullOrWhitespace($STR1)){'empty'} else {'not empty'}
Run Code Online (Sandbox Code Playgroud)

$STR2 = ""
IF ([string]::IsNullOrWhitespace($STR2)){'empty'} else {'not empty'}
Run Code Online (Sandbox Code Playgroud)

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

空!:-)

$STR4 = "Nico"
IF ([string]::IsNullOrWhitespace($STR4)){'empty'} else {'not empty'}
Run Code Online (Sandbox Code Playgroud)

不是空的


Nik*_*hko 9

PowerShell 2.0 替代[string]::IsNullOrWhiteSpace()string -notmatch "\S"

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

> $null  -notmatch "\S"
True
> "   "  -notmatch "\S"
True
> " x "  -notmatch "\S"
False
Run Code Online (Sandbox Code Playgroud)

性能非常接近:

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

> Measure-Command {1..1000000 |% {"   " -notmatch "\S"}}
TotalMilliseconds : 4040.8453
Run Code Online (Sandbox Code Playgroud)


mhe*_*384 5

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

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


Ska*_*inz 5

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

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