数组和-包含-测试数组元素中的子字符串

时间:2019-04-09 13:58:54

标签: powershell substring match contains

我正在尝试过滤掉特定组中的用户。

我在变量中得到以下输出: Group1 Group2 etc...

保存在数组中的每行的一组。我试图只过滤出一个特定的组。但是当我使用-contains时,它总是会说$false,即使在该小组中也是如此。

我的代码:

$group = get-aduser -identity name -properties memberof |
  select-object -expandproperty memberof | %{ (get-adgroup $_).name }

$contains = $group -contains "string"

$contains$false,即使数组中的元素包含字符串...

我想念什么?

2 个答案:

答案 0 :(得分:2)

您的误解是您希望PowerShell的-contains operator对LHS数组的元素执行 substring 匹配
相反,它像数组-eq一样对数组元素进行平等测试-有关详细信息,请参见this answer

针对数组的元素 执行文字子字符串匹配,请使用:

# With non-literal search strings:
[bool] $contains = $group -match ([regex]::Escape($someString))

# With a string literal that doesn't contain regex metachars.,
# escaping isn't needed.
[bool] $contains = $group -match 'foo'

# With a string literal with metachars., you must individually \-escape them.
[bool] $contains = $group -match 'foo\.bar'

注意:

  • 上面显示了一种可靠的通用方法,可确保使用[regex]::Escape()将搜索字符串视为 literal 值,这是必需的,因为 {{1 }}期望 regex regular expression)作为其RHS(搜索模式)

  • 转义并非总是必要的;具体来说,只有存在所谓的元字符(那些在正则表达式中具有特殊含义的字符,例如-match)才需要它,并且当您使用字符串 literal 时,可以选择直接.转义;例如,要搜索文字子串\,您可以传递a.b

    • 有可能AD组名不需要需要转义,但重要的是要意识到一般的需要。
  • 与PowerShell中的所有运算符一样,默认情况下,匹配不区分大小写 ;使用'a\.b'变体进行区分大小写的匹配。

  • 上面约束的-cmatch类型用于确保将[bool]操作的结果转换为布尔值:

    • 虽然-match直接返回带有标量(非数组)LHS的布尔值,而带有 array LHS的布尔值则充当 >过滤器,并返回匹配数组元素 ;在布尔上下文中(例如在-match条件中)进行解释,通常仍能得到预期的结果,因为非空数组被解释为if,而空数组则被解释为$true ;再次,但是重要的是要知道区别。
  • 这在实践中很少会涉及性能,但是值得注意的是, $false由于用作数组的过滤器,总是与 all 数组元素-一旦找到 first 匹配项,它就不会停止,就像-match-contains运算符那样。

    • 从正面看,您可以使用-in来获取匹配的元素本身。

-match执行 substring 匹配的错误期望可能是由于与类似命名但无关的String.Contains() 方法的混淆引起的,它确实执行文字 substring 匹配;例如,-contains产生'foo'.Contains('o')。另外请注意,$true默认情况下区分大小写

PowerShell具有 no 运算符,用于 literal 子字符串匹配。

但是,您可以将PowerShell的通用数组过滤功能与.Contains()字符串方法结合使用-但请注意,这通常会(可能会)比.Contains()方法更糟糕。

合理执行的替代方法是使用PSv4 + -match数组方法,如下所示:

.Where()

从好的方面来说,一旦找到第一个匹配项,此方法就会停止匹配。

答案 1 :(得分:-1)

答案是-match插入了contains。现在输出为true。