Reputation: 1859
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;
}
}
Upvotes: 0
Views: 675
Reputation: 301327
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],"")
Upvotes: 3
Reputation: 29450
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.
Upvotes: 1