提问人:Warlord213 提问时间:5/6/2023 最后编辑:Santiago SquarzonWarlord213 更新时间:5/6/2023 访问量:124
powershell -match string with 如果它具有某个字符之一。即lastname_firstname不匹配lastname_firstname_middleinitail
powershell -match string with if it has one of a certain character. I.E lastname_firstname not match lastname_firstname_middleinitail
问:
我正在尝试匹配只有一个下划线的字符串。Match 目前正在寻找lastname_firstname和lastname_firstname_middleinitail。我只想返回lastname_firstname并排除其他所有内容。
我试过有同样的问题。-match "._." ".(_)." "._{1}" -like "*_*"
这是我的代码中具有 -match 的部分
$newUsers = Get-ADUser -SearchBase "CN=Users,DC=atlantic,DC=county" -Filter {WhenCreated -ge $date7DaysAgo} | Where-Object {$_.name -match "._."}
答:
Where-Object {$_.name -match "_.*?_"}
将检查输入字符串中是否有 2 个或更多下划线,但您想要相反的下划线。因此,您可以使用 NOT 运算符反转输出:$_.name -match "_.*?_"
Where-Object { !($_.name -match "_.*?_") }
评论
$_.name -notmatch '_.*?_'
_
我建议您使用 LDAP 执行部分过滤以减少数据集,从而提高代码效率。 将只搜索其属性至少包含一个的用户,不包括那些没有属性的用户。(name=*_*)
name
_
对于第二层过滤,^[a-z]+_[a-z]+$
将确保名称只有一个,但也只有 to 的字符,如果您需要更具包容性,即名称可能必须 ,您可以使用 。_
a
z
0
9
^[a-z0-9]+_[a-z0-9]+$
$daysAgo = [datetime]::UtcNow.AddDays(-7).ToString('yyyyMMddHHmmss.0Z')
$getADUserSplat = @{
SearchBase = 'CN=Users,DC=atlantic,DC=county'
LDAPFilter = "(&(WhenCreated>=$daysAgo)(name=*_*))"
}
$newUsers = Get-ADUser @getADUserSplat |
Where-Object { $_.Name -match '^[a-z]+_[a-z]+$' }
评论
{WhenCreated -ge $date7DaysAgo}
name -like '*_*'
Filter
LDAPFilter
"whenCreated -ge '$daysAgo' -and name -like '*_*'"
$daysAgo
yyyyMMddHHmmss.0Z
让我补充圣地亚哥的有用答案,这是解决您特定问题的最佳方法,并回答您的问题标题所暗示的一般问题:
对于 N >= 0,如何测试字符串是否恰好包含给定字符的 N 次出现?
$char = '_'
$n = 2
@(
'no underscore',
'one_underscore',
'two_underscores_here'
'three_underscores_are_here'
) |
Where-Object {
# Matches only 'two_underscores_here'
($_ -replace "[^$char]").Length -eq $n
}
注意:
-replace
使用正则表达式实际上删除了除感兴趣字符以外的所有字符,仅保留由感兴趣字符的实例组成的字符串,其长度意味着出现次数。"[^$char]"
对于最多 N 个/小于 N 个和至少 N个/大于 N 个逻辑,请替换为 / 和
-eq
-le
-lt
-ge
/-gt
或者,直接调用 [regex]::Matches()
.NET API:
$char = '_'
$n = 2
@(
'no underscore',
'one_underscore',
'two_underscores_here'
'three_underscores_are_here'
) |
Where-Object {
# Matches only 'two_underscores_here'
([regex]::Matches($_, "[$char]")).Count -eq $n
}
为了完整起见:如果 N 等于 1 或 N 是固定的,或者您需要至少 N 个逻辑,并且您不介意更复杂的正则表达式增加复杂性,您还可以按如下方式使用 -match
:
- 为简单起见,在以下示例中,对感兴趣的字符进行了硬编码。
-
- 为了更容易适应其他角色,即使对于正匹配,它也被包含在其中,即使这不是绝对必要的。
[...]
_
@(
'no underscore',
'one_underscore',
'two_underscores_here'
'three_underscores_are_here'
) |
Where-Object {
# Matches only 'one_underscore'
$_ -match '^[^_]*[_][^_]*$'
}
具有固定 N 值> 1 的示例;请注意,正则表达式部分所需的显式重复(反向引用在一定程度上减轻了这一点)使得这对于较大的 N 值是不切实际的:\1
# N = 2
@(
'no underscore',
'one_underscore',
'two_underscores_here'
'three_underscores_are_here'
) |
Where-Object {
# Matches only 'two_underscores_here'
$_ -match '^[^_]*([_])[^_]*\1[^_]*$'
}
- 有关正则表达式及其试验能力的说明,请参阅此 regex101.com 页。
At-least-N 逻辑大大简化了正则表达式:
# N >= 2
@(
'no underscore',
'one_underscore',
'two_underscores_here'
'three_underscores_are_here'
) |
Where-Object {
# Matches 'two_underscores_here' and 'three_underscores_are_here'
$_ -match '_.*_'
}
N 是 0 的边缘情况最容易处理,因为您需要做的就是确保不存在,这很容易做到:_
-notmatch
# N = 0
@(
'no underscore',
'one_underscore',
'two_underscores_here'
'three_underscores_are_here'
) |
Where-Object {
# Matches only 'no underscore'
$_ -notmatch '[_]'
}
上一个:为什么正则表达式找不到匹配项
下一个:kdb:如何匹配复杂字符串
评论