正则表达式 $pattern.replace 不会替换任何东西

Regex $pattern.replace doesn't replace anything

提问人:Benygreen 提问时间:10/21/2023 最后编辑:phuclvBenygreen 更新时间:10/28/2023 访问量:205

问:

不会替换$regexvar.Replace($var,"str",1)"add"

while(1) {
    $prompt = read-host -prompt [edit]
    if($prompt -eq "exit") {
        Write-Output("Exiting edit.")
        exit
    }
    if($prompt.StartsWith("add")) {
        $lineadd = $prompt
        [regex]$pattern = "add"
        $pattern.Replace($lineadd, "", 1)
        Add-Content -Path ".\$file" -Value "$lineadd"
        Get-Content ".\$file"
  }
}

当我在提示符下键入以下内容时(是提示消息):[edit]:

[edit]: add Test.

我希望输出文件的内容是:

 Test.

但它是:

add Test.

也就是说,没有进行任何替换。

正则表达式 PowerShell 替换

评论

3赞 mozway 10/28/2023
请不要破坏问题。您同意在 CC BY-SA 3.0 许可下发布此内容。
3赞 jmoerdyk 10/28/2023
请不要破坏您的帖子。通过在 Stack Exchange 网络上发布,您已经根据 CC BY-SA 4.0 许可授予了 Stack Exchange 分发该内容的不可撤销权利(即无论您未来的选择如何)。根据 Stack Exchange 策略,帖子的未破坏版本是分发的版本,因此,任何破坏行为都将被恢复。如果您想了解更多关于删除帖子的信息,请参阅:删除工作原理?

答:

1赞 mklement0 10/21/2023 #1

阿卜杜勒·尼亚斯(Abdul Niyas P M)提供了关键的指示:

  • 调用的返回包含结果,该结果始终是一个新字符串$pattern.Replace($lineadd, "", 1)

  • .NET 字符串是不可变的,因此根据定义,不能有就地修改字符串的 .NET API,因此这同样适用于 PowerShell 的字符串运算符

因此(简化示例):

# Sample input string.
$lineadd = 'First add, second add'

# Assign the result of the .Replace() call back to the input-string variable.
$lineadd = ([regex] 'add').Replace($lineadd, '', 1)

# Print $lineadd for diagnostic purposes
# -> 'First , second add', i.e. the first 'add' was effectively removed.
$lineadd 

注意:

  • [regex] 'add'临时构造一个 [regex] 实例 - 不需要严格使用中间变量 ()。$pattern

  • 由于您的意图似乎是限制进行替换的次数(调用中的参数),因此您确实需要一个 [regex] 实例的 .Replace() 方法,假设:1.Replace()

    • [string] 类型的 .Replace() 方法(只执行文字替换)没有此功能。

      • 相反,如果你想确保你的正则表达式从字面上处理搜索字符串,请通过 [regex]::Escape();例如:

        # -> 'First , second ?'
        ([regex] [regex]::Escape('?')).Replace('First ?, second ?', '', 1)
        
    • 同样,PowerShell 的基于正则表达式的 -replace 运算符缺乏限制替换次数的能力。

      • 虽然仍然可以达到相同的效果,但假设事先知道替换的数量,则需要更复杂的正则表达式和替换表达式;例如:

        # -> 'First , second add'
        'First add, second add' -replace 'add(.*)$', '$1'