为什么类似 Powershell 的运算符与我的字符串不匹配?

Why does the Powershell -like operator not match my string?

这里我有 2 个变量:$repo$growth_repo_name_list。这是每个的输出:

> $repo
growth_medicare_consumertargetinganalyzer

> $growth_repo_name_list
2021.2
growth_ifp_consumersummary_v2
growth_ifp_consumertargetinganalyzer
growth_medicare_all_usconsumerattributes
growth_medicare_consumersummary_v2
growth_medicare_consumertargetinganalyzer
growth_medicare_growthopportunityindex
growth_medicare_ifp_all_usconsumerattributes
growth_medicare_ntmtargetinganalyzer
marketintel_medicare_historicalenrollmentanalyzer
marketintel_medicare_planbenefits
memberintel_ifp_aepoepreporting_v2
memberintel_ifp_memberreporting_v2
memberintel_medicaid_memberreporting_v2
memberintel_medicare_aepoepreporting_v2
memberintel_medicare_memberreporting_v2

$repo是一个字符串,$growth_repo_name_list是一个字符串数组:

> $repo.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

> $growth_repo_name_list.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

$repo 没有隐藏字符,如以下代码的输出所示:

> [System.Text.Encoding]::UTF8.GetBytes($repo)
103
114
111
119
116
104
95
109
101
100
105
99
97
114
101
95
99
111
110
115
117
109
101
114
116
97
114
103
101
116
105
110
103
97
110
97
108
121
122
101
114

> [System.Text.Encoding]::UTF8.GetBytes($growth_repo_name_list[5])
103
114
111
119
116
104
95
109
101
100
105
99
97
114
101
95
99
111
110
115
117
109
101
114
116
97
114
103
101
116
105
110
103
97
110
97
108
121
122
101
114

即使我通过双引号将数组转换为扁平字符串,它仍然 returns False:

> "$growth_repo_name_list"
2021.2 growth_ifp_consumersummary_v2 growth_ifp_consumertargetinganalyzer growth_medicare_all_usconsumerattributes growth_medicare_consumersummary_v2 growth_medicare_consumertargetinganalyzer growth_medicare_growthopportunityindex growth_medicare_ifp_all_usconsumerattributes growth_medicare_ntmtargetinganalyzer marketintel_medicare_historicalenrollmentanalyzer marketintel_medicare_planbenefits memberintel_ifp_aepoepreporting_v2 memberintel_ifp_memberreporting_v2 memberintel_medicaid_memberreporting_v2 memberintel_medicare_aepoepreporting_v2 memberintel_medicare_memberreporting_v2

> $ph = "$growth_repo_name_list"

> $repo -like $ph
False

> $ph.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

我在这里做错了什么?比较的结果应该是 True,因为字符串 $repo 包含在列表 $growth_repo_name_list 中。提前感谢您的帮助。

所有比较都会产生 $True,您可能比较错了?

摘自about_Comparison_Operators

When the input is a collection, the operator returns the elements of the collection that match the right-hand value of the expression. If there are no matches in the collection, comparison operators return an empty array

$repo = 'growth_medicare_consumertargetinganalyzer'

$growth_repo_name_list = @(
    '2021.2'
    'growth_ifp_consumersummary_v2'
    'growth_ifp_consumertargetinganalyzer'
    'growth_medicare_all_usconsumerattributes'
    'growth_medicare_consumersummary_v2'
    'growth_medicare_consumertargetinganalyzer'
    'growth_medicare_growthopportunityindex'
    'growth_medicare_ifp_all_usconsumerattributes'
    'growth_medicare_ntmtargetinganalyzer'
    'marketintel_medicare_historicalenrollmentanalyzer'
    'marketintel_medicare_planbenefits'
    'memberintel_ifp_aepoepreporting_v2'
    'memberintel_ifp_memberreporting_v2'
    'memberintel_medicaid_memberreporting_v2'
    'memberintel_medicare_aepoepreporting_v2'
    'memberintel_medicare_memberreporting_v2'
)

[bool]($growth_repo_name_list -like $repo)  # => True
$repo -in $growth_repo_name_list            # => True
$growth_repo_name_list -contains $repo      # => True
[bool]($growth_repo_name_list -match $repo) # => True
$growth_repo_name_list.Contains($repo)      # => True

tl;dr

# Is the value of $repo equal to at least one element of array $growth_repo_name_list?
$repo -in $growth_repo_name_list

注:

  • 默认情况下,-in 执行的每个元素相等比较是大小写不敏感,PowerShell 通常是这样。

  • 但是,您可以在运算符名称前加上 c 前缀,使其区分大小写 (上例中的 -cin . 这适用于 all 字符串处理运算符,包括下面讨论的运算符。


至于你试过的

$repo -like $ph ($ph being "$growth_repo_name_list")
The result of the comparison should be $true since the string $repo is in the list $growth_repo_name_list

否:-likewildcard-matching operator,既不执行(直接)子串匹配,也不支持匹配 RHS 字符串数组

  • 相反,它将 LHS(单个输入字符串或输入字符串数组)与 RHS 上的 单个 wildcard expression 进行比较。
  • 如果您不小心将 array 用作 RHS,则通过将(字符串化的)数组元素与单个 space 在它们之间形成一个字符串 - 这很少有帮助。

因此,直接解决方法是反转操作数:

# *Array* of string inputs. 
# Return those array elements that match the wildcard expression stored in $repo
$growth_repo_name_list -like $repo

这会将数组 $growth_repo_name_list 每个元素 $repo 中的通配符表达式进行比较,并且 return 是 匹配元素的子数组.

布尔值 上下文中使用 return 数组(例如 if ($growth_repo_name_list -like $repo) ...)如果子数组是 ,否则$true

但是,$repo 在您的情况下只是一个字符串 文字 (它不包含通配符元字符,例如 *?) , 所以 没有理由使用 -like - 只需使用 -eq:

# *Array* of string inputs. 
# Return those array elements that are case-insensitively equal to the
# string stored in $repo.
$growth_repo_name_list -eq $repo

反之,如果你想将$repo的值匹配为数组元素的子串

# *Array* of string inputs. 
# Return those array elements that case-insensitively contain the
# string stored in $repo as a substring (or in full).
$growth_repo_name_list -like "*$repo*"

退一步说:看来你只是想测试$repo的值是否包含在$growth_repo_name_list中存储的数组中,即,如果该值完全等于(至少)数组的元素之一。

为此,PowerShell 提供了两个功能等效的运算符 -in and -contains,它们的区别仅在于 操作数顺序:

# Is the value of $repo equal to at least one element of array $growth_repo_name_list?
$repo -in $growth_repo_name_list

# Ditto, operands reversed.
$growth_repo_name_list -contains $repo

这些运算符直接return一个布尔值($true$false)。