1

I am working on a powershell script and I've got several text files where I need to replace backslashes in lines which matches this pattern: .. >\\%name% .. < .. (.. could be anything)

Example string from one of the files where the backslashes should match:

<Tag>\\%name%\TST$\Program\1.0\000\Program.msi</Tag>

Example string from one of the files where the backslashes should not match:

<Tag>/i /L*V "%TST%\filename.log" /quiet /norestart</Tag>

So far I've managed to select every char between >\\%name% and < with this expression (Regex101): (?<=>\\\\%name%)(.*)(?=<) but I failed to select only the backslashes.

Is there a solution which I could not yet find?

Tinnitus
  • 57
  • 1
  • 1
  • 6
  • I'm not 100% but this may not be possible in regex. Your problem is similar to [this](https://stackoverflow.com/questions/3200467/how-to-make-a-group-for-each-word-in-a-sentence) question. I don't see how you can capture every backslash using groups multiple times, without capturing the text between them. – Tom Wyllie Jul 24 '17 at 09:49

2 Answers2

2

I'd recommend selecting the relevant tags with an XPath expression and then do the replacement on the text body of the selected nodes.

$xml.SelectNodes('//Tag[substring(., 1, 8) = "\\%name%"]' | ForEach-Object {
    $_.'#text' = $_.'#text' -replace '\\', '\\'
}
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
0

So here's my solution:

$original_file = $Filepath
$destination_file =  $Filepath + ".new"

Get-Content -Path $original_file | ForEach-Object { 
    $line = $_
    if ($line -match '(?<=>\\\\%name%)(.*)(?=<)'){
       $line = $line -replace '\\','/'
     }
    $line
} | Set-Content -Path $destination_file
Remove-Item $original_file
Rename-Item $destination_file.ToString() $original_file.ToString()

So this will replace every \ with an / in the given pattern but not in the way which my question was about.

Tinnitus
  • 57
  • 1
  • 1
  • 6