我正在尝试在几百页中找到一个函数并使用Powershell将其删除。我可以在一条线上匹配,但是我遇到了让多线匹配工作的问题。任何帮助将不胜感激。
我试图找到的功能:
Protected Function MyFunction(ByVal ID As Integer) As Boolean
Return list.IsMyFunction()
End Function
我正在使用的代码与多行不匹配:
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;
}
}
答案 0 :(得分:3)
您可以在正则表达式上使用(?s)
标志。 S表示单行,在某些地方也称为dotall,这使.
在新行中匹配。
此外,gc
逐行读取,任何比较/匹配将在各行和正则表达式之间。尽管在正则表达式上使用了正确的标志,但你不会得到匹配。我通常使用[System.IO.File]::ReadAllText()
将整个文件的内容作为单个字符串。
因此,一个有效的解决方案将是:
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;
}
}
对于替换,您当然可以使用$matches[0]
并使用Replace()
方法
$newc = $c.Replace($matches[0],"")
答案 1 :(得分:1)
默认情况下,-match运算符不会通过回车符搜索。*。您需要直接使用.Net Regex.Match函数来指定“单行”(在这种情况下不幸命名)搜索选项:
[Regex]::Match($c,
"(?m)Protected Function MyFunction\(ByVal ID As Integer\) As Boolean.*End Function",
'Singleline')
有关详情,请参阅MSDN中的Match功能和valid regex options。