【问题标题】:PowerShell -match with -simplematchPowerShell -match 与 -simplematch
【发布时间】:2020-04-17 11:53:54
【问题描述】:

我有一些运行良好的代码

if ($myinput -match "$cmd") { $cmd = $cmd -replace "test", "output" }

后来,我意识到我不希望匹配是正则表达式,而只是文字简单匹配。即我只想知道 $myinput 是否包含 $cmd 字符串中的内容(即使 * . \ 等在该字符串中)。我应该将-match 更改为不同的运算符,还是可以在此处添加标志或修改以告诉它进行文字匹配?

【问题讨论】:

  • 您可以保持不变,只需将 -match $cmd 更改为 -match [regex]::Escape($cmd),前提是您在 $cmd 中没有特殊的正则表达式字符。
  • 您也可以使用[wildcardpattern]::Escape($cmd)。然后用星号包围$cmd 并使用-like 或只使用-eq
  • 令人着迷。我以前从未见过这种东西。也可能很好,因为我认为-match-like 快很多(我不明白为什么,我原以为-like 更简单,因此更快,但各种网站似乎表明-match 是更快),所以也许我可以将 -match 用于文字匹配的所有内容!现在测试,效果很好,谢谢!

标签: regex powershell match


【解决方案1】:

我不知道在没有正则表达式的情况下使-match 工作的方法,但是您可以使用许多选项。

选项 1:转义 -match 中的正则表达式字符

如果$cmd 不包含您打算用作正则表达式的任何特殊正则表达式字符,您可以简单地转义字符串。即使您仍在使用正则表达式,您仍在搜索文字字符串。

$cmd = [regex]::Escape('str*ng.txt')
$cmd
str\*ng\.txt

'string.txt' -match $cmd
False
'str*ng.txt' -match $cmd
True
'BEGIN str*ng.txtEND' -match $cmd
True

-match 的行为是它将在整个字符串中搜索您的匹配项,除非您使用锚字符。


选项 2:将 -eq-like 与文字字符串一起使用

如果使用-eq,您必须期待完全匹配。您的搜索字符串必须在字面上与目标字符串匹配,并且不存在子字符串匹配。使用-like,您仍然可以进行子字符串匹配,但需要使用通配符。

# Testing with -eq
$cmd = 'str*ng.txt'
'string.txt' -eq $cmd
False
'str*ng.txt' -eq $cmd
True
'BEGINstr*ng.txt' -eq $cmd
False

# Testing with -like without escaping wildcards
$cmd = 'str*ng.txt'
'str*ng.txt' -like $cmd
True
'BEGINstr*ng.txt' -like $cmd
False

# Testing with -like while combining escaped wildcard chars and using wildcards
$cmd = [wildcardpattern]::Escape('str*ng.txt')
$cmd
str`*ng.txt
$cmd = "*{0}*" -f $cmd
$cmd
*str`*ng.txt*
'str*ng.txt' -like $cmd
True
'BEGINstr*ng.txt' -like $cmd
True

-eq-like 的行为要求您了解整个字符串或了解使用哪些通配符来返回正确的结果。


选项 3:使用 Select-String

Select-String 支持-SimpleMatch 开关。这默认情况下会进行文字字符串的子字符串匹配。

$cmd = 'str*ng.txt'
if ('string.txt' | Select-String -Pattern $cmd -SimpleMatch) {
    'Match Found'
} else {
    'Match not Found'
}
Match not Found

if ('str*ng.txt' | Select-String -Pattern $cmd -SimpleMatch) {
    'Match Found'
} else {
    'Match not Found'
}
Match Found

【讨论】:

    【解决方案2】:

    您可以使用.contains()。请注意,它对一个参数区分大小写。 $input 是 powershell 中的 automatic variable

    if ($myinput.contains("$cmd")) { $cmd = $cmd -replace "test", "output" }
    

    【讨论】:

    • 啊,我的错,我将实际代码中变量的奇怪名称更改为我认为更通用的名称,$input 是一个糟糕的选择!我已将 OP 更新为 $myinput 以避免混淆。所以这很有趣。我看到您没有使用 PowerShell -contains 运算符(专门用于集合!),而是使用 .NET .contains()。这也是我没有考虑过的非常有趣的方法。我将来肯定也会利用这个。非常有用,谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多