Search code examples
powershellpowershell-4.0

Why this code works in PowerShell but it doesn't change nothing in the html file (with Regex)


I have file1.html with this lines:

<bogus></bogus>
 <title>Something goes here</title>
 <TheEnd>END</TheEnd>

I made 3 different PowerShell scripts with regex in order to change this line: <title>Something goes here</title>:

  $path = 'c:\Folder1\file1.html'
  $Content = Get-Content -Path $path
           
  foreach($Line in $Content){
      $Line -replace "<title>(.*?)</title>",'$1 NEW is now there!'  #This regex selects everything between tags and make a replace:
  }
  Set-Content -Path $Path -Value $Line

AND

$Content = Get-Content -Path c:\Folder1\file1.html  
  
   foreach($Line in $Content){
       $Line -replace "<title>(.*?)</title>",'$1 NEW is now there!'  #This regex selects everything between tags and make a replace:
   }
  Set-Content -Path $Path -Value $Line

OR

$path = 'c:\Folder1\file1.html'
$Content = Get-Content -Path $path  
$GetTitle = [regex]"<title>(.*?)</title>"
 foreach($Line in $Content){
     $Line -replace $GetTitle,'$1 NEW is now there!'  #This regex selects everything between tags and make a replace:
 }
  Set-Content -Path $Path -Value $Line

The output should be.

<bogus></bogus>

<title>NEW is now there!</title>

<TheEnd>END</TheEnd>

Mention that all my codes are working in PowerShell, but does not make any change in File1.html. That is the problem. can anyone correct my codes?


Solution

  • With regex -replace, you need to think what you want to keep and capture that in backreferences. In your case, you want to retain <title> and </title>, and replace what is in between those tags.

    Change the regex to '(<title>).*?(</title>)'.

    Also, you can use the -Raw switch on Get-Content to read the file as a single multilined string, do the replacement and pipe the result straight through to Set-Content

    $path = 'c:\Folder1\file1.html'
    (Get-Content -Path $path -Raw) -replace '(<title>).*?(</title>)', '$1NEW is now there!$2' |
        Set-Content -Path $Path
    

    Details:

    '$1' +                     Insert the text that was last matched by capturing group number 1
    ' NEW is now there!' +     Insert the character string “ NEW is now there!” literally
    '$2'                       Insert the text that was last matched by capturing group number 2