用于查找和删除函数的 Powershell 正则表达式

发布于 2024-12-08 00:29:29 字数 501 浏览 1 评论 0原文

我试图在几百页中找到一个函数并使用 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;
  }
}

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;
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苦行僧 2024-12-15 00:29:29

您可以在正则表达式上使用 (?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],"")

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],"")
阳光①夏 2024-12-15 00:29:29

默认情况下,-match 运算符不会通过回车符搜索 .*。您将需要直接使用 .Net Regex.Match 函数来指定“单行”(不幸的是在本例中命名)搜索选项:

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

请参阅 匹配函数和有效的正则表达式选项。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文