如何在PowerShell中将变量用作正则表达式的一部分?

时间:2018-05-07 09:15:17

标签: regex powershell

我想Select-String文件路径的一部分,从一个变量中包含的字符串值开始。让我在抽象的例子中解释一下。

让我们假设这条路径:/ docs / reports / test reports / document1.docx

使用正则表达式我可以得到所需的字符串: '^.*(?=\/test\s)'

https://regex101.com/r/6mBhLX/5

结果字符串是'/ test reports / document1.docx'。

现在,为了实现这一点,我必须使用文字字符串'test'。但是,我想知道如何使用包含'test'的变量,例如$的myString。

我已经查看了How do you use a variable in a regular expression?,但我无法弄清楚如何为PowerShell进行调整。

谢谢!

3 个答案:

答案 0 :(得分:5)

我建议在双引号字符串文字中使用$([regex]::escape($myString))

$myString="[test]"
$pattern = "^.*(?=/$([regex]::escape($myString))\s)"

或者,如果您不想担心额外的转义,请使用+运算符进行常规连接:

$pattern = '^.*(?=/' + [regex]::escape($myString) +'\s)'

结果$pattern看起来像^.*(?=/\[test]\s)。由于$myString变量是文字字符串,因此您需要转义所有特殊的正则表达式元字符(带有[regex]::escape()),以便正则表达式引擎将其解释为文字字符。

在您的情况下,您可以使用

$s = '/docs/reports/test reports/document1.docx'
$myString="test"
$pattern = "^.*(?=/$([regex]::escape($myString))\s)"
$s -replace $pattern

结果:/test reports/document1.docx

答案 1 :(得分:1)

Wiktor Stribiżew's helpful answer提供了关键指针:

使用 [regex]::Escape() 以转义字符串,以便安全地包含在正则表达式(正则表达式)中,以便将其视为文字;
例如,[regex]::Escape('$10?')产生\$10\? - 对正则表达式具有特殊含义的字符为\ - 已转义。

但是,我建议使用'...' ,即从单个引用字符串构建正则表达式:

$myString='test'
$regex = '^.*(?=/' + [regex]::escape($myString) + '\s)'

使用-f运算符 - $regex = '^.*(?=/{0}'\s)' -f [regex]::Escape($myString)也可以在视觉上更清晰,但请注意-f - 与+的字符串连接不同 - 是文化 - 敏感,可能导致不同的结果。

在PowerShell中使用正则表达式上下文中的'...'字符串是一种形成的好习惯

  • 通过避免"...",您可以避免字符串的额外前置解释(插值又称扩展),这会产生意想不到的效果,因为$中具有特殊含义两个上下文:开头 字符串扩展时的变量引用或子表达式,以及正则表达式中的输入结束标记。

  • 在基于正则表达式的"..."运算符的替换字符串中使用-replace可能会特别棘手,其中$1等标记引用捕获组结果,如果您使用"$1",PowerShell会尝试展开$1 变量,这可能不存在,导致空字符串

答案 2 :(得分:0)


只需在双引号(“pattern”)中写入变量,如下所示:

PS > $pattern = "^\d+\w+"
PS > "357test*&(fdnsajkfj" -match $pattern          # return true
PS > "357test*&(fdnsajkfj" -match "$pattern.*\w+$"  # return true
PS > "357test*&(fdnsajkfj" -match "$pattern\w+$"    # return false

请试一试。 :)