powershell 为什么-Match运算符有时返回匹配的字符串,有时返回布尔值?

nlejzf6q  于 2023-01-09  发布在  Shell
关注(0)|答案(2)|浏览(157)

这是Powershell中我最喜欢的操作符,但有时我觉得它鄙视我!!
假设在$Clipboard中有一个字符串:

PowerShell Documentation - PowerShell | Microsoft Learn
https://learn.microsoft.com/en-us/powershell/

Welcome to Python.org
https://www.python.org/

GitHub
https://github.com/

调用:

$Clipboard.trim()  -split '\n' -NotMatch "^$"

返回匹配的实际字符串,而不是布尔值:

PowerShell Documentation - PowerShell | Microsoft Learn
https://learn.microsoft.com/en-us/powershell/
Welcome to Python.org
https://www.python.org/
GitHub
https://github.com/

然而,如果我这样做:

$Clipboard.trim()  -split '\n' -NotMatch "^$"| % {$Title = $_ -Match "https?:|//www\." 
$Title
}

我得到布尔值:

False
True
False
True
False
True

我现在开始避开-Match,请发送帮助。

ru9i0ody

ru9i0ody1#

这是PowerShell的 * 比较 * 运算符*一般 * 特性:

  • 使用*标量 *(单个)LHS操作数时,它们返回[bool]结果($true$false)。
  • 对于数组 (集合)LHS操作数,它们充当 * 过滤器***,并返回 * 与*匹配的LHS元素(总是)作为数组。

关于-match运算符,特别注意,包含关于匹配了 * 什么 * 的信息的自动$Matches变量仅用 * 标量 * LHS填充。
正如iRon所指出的,PowerShell的隐式到布尔的强制规则还允许您使用带有数组值LHS * 的操作作为条件*;例如:

# -> 'MATCH found',
# because the -match operation returns @('foo'), i.e.
# the subarray of matching items, and [bool] @('foo') is $true.
if (@('foo', 'bar') -match 'f') { 'MATCH found' } else { 'NO match' }

# -> 'NO match',
# because the -match operation returns @(), i.e. an *empty array,
# and [bool] @() is $false
if (@('foo', 'bar') -match 'x') { 'MATCH found' } else { 'NO match' }

但是,存在陷阱,即当过滤操作返回一个***single * 结果,而该结果在强制为[bool]时恰好为$false**请注意,即使在这种情况下返回一个单元素 * array *,PowerShell也会将其视为其在此上下文中的唯一元素:

# !! -> 'NO match', even though a match *was* found: 
# !! The -match operation returns @('') and [bool] @('') is the
# !! same as [bool] '' and therefore $false.
if (@('', 'bar') -match 'foo|^$') { 'MATCH found' } else { 'NO match' }

# !! -> 'NO match', even though a match *was* found: 
# !! The -eq operation returns @(0) and [bool] @(0) is 
# !! the same as [bool] 0 and therefore $false.
if (@(0, 1) -eq 0) { 'MATCH found' } else { 'NO match' }

如果返回 * 两个或更多 * 结果,则强制结果 * 总是 * $true,无论数组元素的值如何(类似于 * no * 结果,即空返回数组总是生成$false)。

    • PowerShell的布尔转换规则**摘要在this answer的底部。
cngwdvgl

cngwdvgl2#

这是设计好的。在第一个示例中,在取回字符串的地方,您将一个集合传递给-match,它执行隐式枚举并返回匹配的字符串。在第二个示例中,您自己枚举集合并单独测试每一项,因此使用Boolean
此行为在-match运算符帮助中有明确说明:
当这些运算符的输入是标量值时,它们返回布尔值。当输入是值的集合时,运算符返回任何匹配的成员。如果集合中没有匹配项,运算符返回空数组。

相关问题