电源外壳替换 - 特殊字符



我需要替换

location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:32583;

location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:$proxy;

我正在尝试使用以下代码实现此目的,但没有成功

Get-ChildItem 'C:nginxconfnginx.conf' | ForEach {
(Get-Content $_) | ForEach  {$_ -Replace "location ~* ""^/(888888-localhost\/client)(.*)$"" {
proxy_pass https://localhost:.+;", "location ~* ""^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:$proxy;""} | Set-Content $_
}

如何使用Powershell执行此操作?

一种解决方案是使用积极的回溯来确保模式匹配:

@"
location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:32583;
"@  -replace "(?<=/localhost:)d+",'$port'
# In your use-case
(Get-Content -Path ($Path = 'C:nginxconfnginx.conf')) -replace "(?<=/localhost:)d+",'$port' | 
Set-Content -Path $Path

删除$port两边的单引号或用双引号替换它们将允许使用$port作为实际变量。

  • 由于要行匹配,因此无法使用Get-Content默认执行的逐行处理。使用-Raw开关一次将整个文件读取为单个多行字符串。

  • 由于搜索字符串和传递给基于 regex 的-replace运算符的替换字符串都包含元字符,因此必须对它们进行转义

    • 注意:如果您只需要文字(逐字)子字符串匹配,包括不需要断言子字符串必须匹配的位置(字符串的开头、单词边界等),则使用[string]::Replace()是更简单的选项,但是:

      • 在Windows PowerShell中,[string]::Replace()总是区分大小写,在PowerShell(Core)7+中,它默认区分大小写,与PowerShell的运算符不同 - 有关何时使用-replace与何时使用的指导,请参阅此答案。[string]::Replace()
    • 搜索字符串必须使用[regex]::Escape()进行转义,以便-replace运算符始终使用的 .NET 正则表达式引擎将其视为文本。

    • 替换字符串必须将任何嵌入的$字符转义为$$,以便$不会被误认为是捕获组引用的开头。

    • 有关-replace工作原理的全面概述,请参阅此答案。

# Escape the search string.
$reSearch = [regex]::Escape(@'
location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:32583;
@')
# Escape the substitution string.
$substitution = @"
location ~* "^/(888888-localhost/client)(.*)$" {
proxy_pass https://localhost:$proxy;
"@.Replace('$', '$$')
# ...
($_ | Get-Content -Raw) -replace $reSearch, $substitution |
Set-Content -LiteralPath $_.FullName
# ...

请注意逐字和可扩展的此处字符串的使用,以便于声明字符串。

至于简化您的-replace操作

  • Abraham Zinala指出,最终你只希望替换匹配子字符串中的端口号,所以你可以使用一个积极的后视断言((?<=...)),如这个简化的例子所示:

    $proxy = 8080
    'a https://localhost:80; z' -replace '(?<=https://localhost:)d+', $proxy
    
    • 输出为:a https://localhost:8080; z

行符警告:

  • 以上假定您的脚本文件使用与输入文件相同的换行符格式(Windows 格式的 CRLF 与 Unix 格式的 LF)。

  • 如果您不确定,并且想要匹配任一格式,请根据需要将$reSearch中的n转义序列替换为r?n($reSearch = $reSearch.Replace('n', 'r?n'),并可能根据需要将$substitution中的文字换行符替换为`r`n`n

最新更新