在PowerShell中无法定位和替换字符串,此字符串类似于带有‘%’的路径

7rtdyuoh  于 2022-11-10  发布在  Shell
关注(0)|答案(1)|浏览(144)

我正在尝试更新HTM文件中的徽标,我们有两个路径需要更换
紧随其后的是工作正常并被取代的产品。
原始字符串

<img src=C:\ProductName\ProductNameClient\webapps\ProductNameClient\assets\img\logo\logo.jpg alt='ProductName Logo'>

由于转义序列问题而更新,我们正在使用PowerShell中的以下字符串来搜索原始字符串

<img src=C:\\ProductName\\ProductNameClient\\webapps\\ProductNameClient\\assets\\img\\logo\\logo.jpg alt='ProductName Logo'>

替换字符串

<img src=../../ProductNameNew/ProductNameNewLogo.png alt='ProductNameNew Logo'>

PowerShell脚本对此字符串工作正常

Get-ChildItem -Path (Get-Item .).FullName -Recurse -File *.htm | ForEach-Object {
 $content = Get-Content -Path $_.FullName
  if($content -match "<img src=C:\\ProductName\\ProductNameClient\\webapps\\ProductNameClient\\assets\\img\\logo\\logo.jpg alt='ProductName Logo'>"){
     $content -replace "<img src=C:\\ProductName\\ProductNameClient\\webapps\\ProductNameClient\\assets\\img\\logo\\logo.jpg alt='ProductName Logo'>","<img src=../../ProductNameNew/ProductNameNewLogo.png alt='ProductNameNew Logo'>" | Set-Content -Path $_.FullName
  }}

我使用了相同的PowerShell脚本并更新了转义序列的字符串
不使用此字符串原始字符串

<img src=C:\Program%20Files%20(x86)\ProductName\.\ProductNameConfigs\ProductNameOLDlogo.png alt='ProductName Logo'>

更新到期转义序列问题

<img src=C:\\Program%20Files%20(x86)\\ProductName\\.\\ProductNameConfigs\\ProductNameOLDlogo.png alt='ProductName Logo'>

替换字符串

<img src=../../../ProductNameNew/ProductNameNewLogo.png alt='ProductNameNew Logo'>

我使用了对上一次更新有效的转义序列,但现在它不起作用了,我在PowerShell中没有收到任何错误来解决这个问题,脚本将执行,字符串将保持不变,PowerShell中没有错误

Get-ChildItem -Path (Get-Item .).FullName -Recurse -File *.htm | ForEach-Object {
 $content = Get-Content -Path $_.FullName
  if($content -match "<img src=C:\\Program%20Files%20(x86)\\ProductName\\.\\ProductNameConfigs\\ProductNameOLDlogo.png alt='ProductName Logo'>"){
     $content -replace "<img src=C:\\Program%20Files%20(x86)\\ProductName\\.\\ProductNameConfigs\\ProductNameOLDlogo.png alt='ProductName Logo'>","<img src=../../../ProductNameNew/ProductNameNewLogo.png alt='ProductNameNew Logo'>" | Set-Content -Path $_.FullName
  }}

当我运行并检查它没有更新时,有人能给我提供一些输入吗

rta7y2nd

rta7y2nd1#

除了反斜杠之外,还有更多的字符需要转义,比如圆括号和圆点。对于要在-matchRegular Expression中用作文字模式的“原始字符串”,这意味着:

[Regex]::Escape("<img src=C:\Program%20Files%20(x86)\ProductName\.\ProductNameConfigs\ProductNameOLDlogo.png alt='ProductName Logo'>")
<img\ src=C:\\Program%20Files%20\(x86\)\\ProductName\\\.\\ProductNameConfigs\\ProductNameOLDlogo\.png\ alt='ProductName\ Logo'>

因此:

...
$Pattern = [Regex]::Escape("<img src=C:\Program%20Files%20(x86)\ProductName\.\ProductNameConfigs\ProductNameOLDlogo.png alt='ProductName Logo'>")
if ($content -match $Pattern) { ...

无论如何,它通常是a bad idea to attempt to parse HTML with regular expressions
相反,您可以考虑使用专用的HTML解析器作为HtmlDocumentclass

$Html = @'
    <!DOCTYPE html>
    <html>
    <body>

    <h2>HTML Images</h2>
    <p>HTML images are defined with the img tag:</p>

    <img src=C:\Program%20Files%20(x86)\ProductName\.\ProductNameConfigs\ProductNameOLDlogo.png alt='ProductName Logo'>

    </body>
    </html>
'@
function ParseHtml($String) {
    $Unicode = [System.Text.Encoding]::Unicode.GetBytes($String)
    $Html = New-Object -Com 'HTMLFile'
    if ($Html.PSObject.Methods.Name -Contains 'IHTMLDocument2_Write') {
        $Html.IHTMLDocument2_Write($Unicode)
    } 
    else {
        $Html.write($Unicode)
    }
    $Html.Close()
    $Html
}

$Document = ParseHtml $Html
$Document.getElementsByTagName('img') |ForEach-Object {
    if (  $_.nameProp -eq 'ProductNameOLDlogo.png' ) {
        $_.src = [uri]::EscapeDataString('../../../ProductNameNew/ProductNameNewLogo.png')
        $_.alt = 'ProductNameNew Logo'
    }
}

@"
<!DOCTYPE html>
<html>
$($Document.body.outerHtml)
</html>
"@

相关问题