0

I'm trying to find a function in a few hundred pages and remove it using Powershell. I can match on a single line but I'm having issues getting a multi-line match to work. Any help would be appreciated.

Function I'm trying to find:

Protected Function MyFunction(ByVal ID As Integer) As Boolean
    Return list.IsMyFunction()  
End Function

Code I'm using that won't match multi-line:

gci -recurse | ?{$_.Name -match "(?i)MyPage.*\.aspx"} | %{
  $c = gc $_.FullName;
  if ($c -match "(?m)Protected Function MyFunction\(ByVal ID As Integer\) As Boolean.*End Function")  {
    $_.Fullname | write-host;
  }
}
Brian Ellis
  • 1,829
  • 1
  • 19
  • 24

2 Answers2

3

You can use the (?s) flag on the regex. S for singleline, also called, dotall in some places, which makes . match across newlines.

Also, gc reads line by line and any comparision / match will be between individual lines and the regex. You will not get a match despite using proper flags on the regex. I usually use [System.IO.File]::ReadAllText() to get the entire file's contents as a single string.

So a working solution will be something like:

gci -recurse | ?{$_.Name -match "(?i)MyPage.*\.aspx"} | %{
  $c = [System.IO.File]::ReadAllText($_.Fullname)
  if ($c -match "(?s)Protected Function MyFunction\(ByVal ID As Integer\) As Boolean.*End Function")  {
    $_.Fullname | write-host;
  }

}

For the replace, you can of course use $matches[0] and use the Replace() method

$newc = $c.Replace($matches[0],"")
manojlds
  • 290,304
  • 63
  • 469
  • 417
1

By default, the -match operator will not search for .* through carriage returns. You will need to use the .Net Regex.Match function directly to specify the 'singleline' (unfortunately named in this case) search option:

[Regex]::Match($c,
               "(?m)Protected Function MyFunction\(ByVal ID As Integer\) As Boolean.*End Function", 
               'Singleline')

See the Match function and valid regex options in the MSDN for more details.

zdan
  • 28,667
  • 7
  • 60
  • 71
  • This solution works great for search. The reason I didn't choose it as the answer is that I then had a problem with writing the content back out. To use the .net [regex]::replace function would strip out line breaks, while the solution I marked as the answer fixes the search issue and also preserves the formatting for set-content. For more details, see http://stackoverflow.com/questions/2726599/powershell-replace-lose-line-breaks Thanks again. – Brian Ellis Oct 05 '11 at 19:33