【问题标题】:Powershell -replace giving strange behaviourPowershell -replace 给出奇怪的行为
【发布时间】:2020-10-05 06:41:45
【问题描述】:

这快把我逼疯了!希望能提供任何关于发生了什么的指示!

$alpha = 'aaa.bbb.$connection.ccc.ddd'
$s = [regex]::match($alpha,"\$.+?(?=\.)").Value

"Alpha is: $alpha"
"Matched chunk is: $s"

$newChunk = "'" + $s + "'"
"New chunk is: $newChunk"

$beta = $alpha -replace $s,$newChunk
"Beta is: $beta"

这会产生以下输出:

Alpha is: aaa.bbb.$connection.ccc.ddd
Matched chunk is: $connection
New chunk is: '$connection'
Beta is: aaa.bbb.$connection.ccc.ddd

我正在尝试识别/匹配以文字“$”开头的路径中的字符序列并继续直到,但不包括文字点“。”字符。在上面的示例代码中,字符串将是“$connection”。

然后我需要将该字符串用单引号括起来,因此在上面的示例中,$newChunk 值将变为 '$connection',包括单引号。

接下来,我需要将匹配的值替换为原始字符串中的新单引号值。无论我尝试什么(与 [regex]::match 方法相同),单引号都会被删除。所以,实际上,我正试图转向:

aaa.bbb.$connection.ccc.ddd

进入

aaa.bbb.'$connection'.ccc.ddd

使用 Powershell 7.1,非常感谢有人告诉我为什么这不起作用。谢谢!

【问题讨论】:

  • 感谢您提供的丰富细节。确实很有帮助!是的,我认为 -replace 只会替换字符串文字。我从来没有想过开头的 $ 可能会被解释。非常感谢。

标签: regex powershell


【解决方案1】:

使用

$beta = $alpha -replace '\$[^.]+', "'$&'"

proof

说明

--------------------------------------------------------------------------------
  \$                       '$'
--------------------------------------------------------------------------------
  [^.]+                    any character except: '.' (1 or more times
                           (matching the most amount possible))

$& 是整个比赛的占位符。

【讨论】:

  • 美丽的答案,让我再次出发 - 谢谢!如果有人知道,我很想知道为什么原始代码不起作用?谢谢Ryszard
  • @Indrid 你使用了$s,持有$connection,当用作正则表达式时,匹配字符串的结尾跟connection。这不可能发生。你需要转义$,也许使用[regex]::escape。不过无需这样做,$& 旨在用于此类情况。
  • 优秀。非常感谢!
【解决方案2】:

Ryszard Czech's helpful answer 绝对是最好的解决方案:一般指的是 基于正则表达式 -replace operator 在其替换操作数中匹配的内容, 占位符$& 是最简单、最可靠的解决方案。

请参阅this answer 了解您可以使用的其他占位符,例如preceded ($`) 或succeeded ($' ) 匹配,或者 捕获组 匹配的内容(例如$1)。


至于你尝试了什么

  • 您没有将正则表达式 \$.+?(?=\.) 直接基于正则表达式的 -replace operator 一起使用,而是使用了显式的逐字结果 [regex].Match() 调用作为 -replace 的搜索操作数(第一个 RHS 操作数),然后再次将其解释为正则表达式。

    • 然而,为了使用字符串逐字作为-replace搜索操作数,任何正则表达式元字符 - 即具有特殊句法含义的字符 - 必须是\-转义,例如字符串中的逐字$,您可以使用[regex]::Escape($s)
  • 此外,您使用了一个 替换操作数,其中嵌入了一个 $ 字符。 您打算逐字逐句解释它,但是 @替换操作数中的 987654340@ 是一个元字符,指的是占位符,例如$&

    • 为了将字符串逐字用作-replace 替换操作数,您必须以编程方式 转义嵌入$ 字符。作为$$[1]:
      最简单的方法是使用[string] 类型的文字子字符串替换方法.Replace()

      $replacementOperand = '$foo'    
      'value is: (value)' -replace '\(value\)', $replacementOperand.Replace('$', '$$') 
      

因此,您的原始方法必须使用以下命令 - 但请注意,Ryszard 的解决方案总体上要简单得多:

$beta = $alpha -replace [regex]::replace($s), $newChunk.Replace('$', '$$')

[1] 在某些情况下您可能会逃脱而无需转义,因为未被识别为占位符的带有 $ 前缀的令牌被留下未触及 (例如,'bar' -replace 'r', '$x' 的行为与'bar' -replace 'r', '$$x' 相同),但唯一稳健 的解决方案是逐字转义$ 字符。将它们翻倍。

【讨论】:

    猜你喜欢
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2020-01-19
    • 2021-10-02
    • 2018-10-17
    • 2016-11-06
    • 2014-06-05
    相关资源
    最近更新 更多