数组和 -contains - 测试数组元素中的子字符串 [英] Arrays and -contains - test for substrings in the elements of an array

查看:25
本文介绍了数组和 -contains - 测试数组元素中的子字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to filter out users that are in a specific group.

我在一个变量中得到以下输出:<代码>第一组组2等等...

I got the following output in a variable: Group1 Group2 etc...

保存在数组中的每一行一组.我试图只过滤掉一个特定的组.但是当我使用 -contains 时,它总是显示 $false,即使该组在那里.

One group for each line saved in an array. Im trying to filter out only one specific group. But when I use -contains it always says $false, even tho the group is there.

我的代码:

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

$contains = $group -contains "string"

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

$contains is $false even if the array has elements that contain the string...

我错过了什么?

推荐答案

看起来您的误解是您期望 PowerShell 的 -contains 运算符 执行子串匹配 反对 LHS 数组的元素.
相反,它执行相等测试 - 正如 -eq 所做的那样 - 针对数组的元素 - 参见 此答案 了解详情.

It looks like your misconception was that you expected PowerShell's -contains operator to perform substring matching against the elements of the LHS array.
Instead, it performs equality tests - as -eq would - against the array's elements - see this answer for details.

为了数组元素执行字面子字符串匹配,请使用:

# 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() 来确保您的搜索字符串被视为文字值的强大、通用的方法,这是必要的,因为 -match 需要 regex (正则表达式) 作为其 RHS(搜索模式).

  • The above shows a robust, generic way of ensuring that your search string is treated as a literal value using [regex]::Escape(), which is necessary because -match expects a regex (regular expression) as its RHS (the search pattern).

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

Escaping isn't always necessary; specifically, only the presence of so-called metacharacters (those with special meaning in a regex, such as .) requires it, and when you're using a string literal, you can opt to directly -escape them; e.g., to search for literal substring a.b, you can pass 'a.b'.

  • AD 组名称可能不需要需要转义,但重要的是要注意一般需要转义.
  • Chances are that AD group names do not require escaping, but it's important to be aware of the need for it in general.

与 PowerShell 中的所有运算符一样,默认情况下匹配不区分大小写;使用 -cmatch 变体进行区分大小写的匹配.

As with all operators in PowerShell, by default the matching is case-insensitive; use the -cmatch variant for case-sensitive matching.

上面约束的[bool]类型用于保证-match操作的结果被转换为布尔值:

The [bool] type constrained above is used to ensure that the result of the -match operation is converted to a Boolean:

  • 虽然 -match 直接返回一个带有 scalar(非数组)LHS 的布尔值,但它带有一个 array LHS作为过滤器,并返回匹配的数组元素;在布尔上下文中解释,例如在 if 条件中,通常仍会给出预期结果,因为非空数组被解释为 $true,而空数组被解释为一个为 $false;再次重申,但了解差异很重要.
  • While -match directly returns a Boolean with a scalar (non-array) LHS, with an array LHS it acts as a filter, and returns the matching array elements instead; interpreted in a Boolean context, such as in an if conditional, that usually still gives the expected result, because a non-empty array is interpreted as $true, whereas an empty one as $false; again, however it's important to know the difference.

这在实践中很少会成为性能问题,但值得注意的是 -match,由于充当数组的过滤器,总是与 匹配所有 数组元素 - 一旦找到第一个 匹配,它就不会停止,-contains-in 的方式 操作符可以.

This will rarely be a performance concern in practice, but it is worth noting that -match, due to acting as a filter with arrays, always matches against all array elements - it doesn't stop once the first match is found, the way that the -contains and -in operators do.

  • 从好的方面来说,您可以使用 -match 来获取匹配元素本身.
  • On the plus side, you can use -match to obtain the matching elements themselves.

错误期望 -contains 执行 substring 匹配可能源于 与名称相似但不相关的 String.Contains() 方法,它确实执行文字 substring 匹配;例如,'foo'.Contains('o') 产生 $true.另请注意,.Contains() 默认情况下区分大小写.

The mistaken expectation of -contains performing substring matching may have arisen from confusion with the similarly named, but unrelated String.Contains() method, which indeed performs literal substring matching; e.g., 'foo'.Contains('o') yields $true. Also note that .Contains() is case-sensitive by default.

PowerShell 没有运算符用于文字子字符串匹配.

PowerShell has no operator for literal substring matching.

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

However, you could combine PowerShell's generic array-filtering features with the .Contains() string method - but note that this will typically perform (potentially much) worse than the -match approach.

一种性能合理的替代方法是使用 PSv4+ .Where() 数组方法,如下所示:

A reasonably performant alternative is to use the PSv4+ .Where() array method as follows:

# Note: Substring search is case-sensitive here.
[bool] $contains = $group.Where({ $_.Contains("string") }, 'First')

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

On the plus side, this approach stops matching once the first match is found.

这篇关于数组和 -contains - 测试数组元素中的子字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆