在PowerShell中进行多行正则表达式匹配,无论是否提前行

问题描述

我正在尝试格式化降价文件,以便在标题后有一个空行,该文件是用UTF8换行符编码的CRLF,下面是示例文件

## DESCRIPTION
description entry...

## EXAMPLES

### EXAMPLE 1
```
some example here...
```

## OUTPUTS
## NOTES

在这里我要查找所有不带空行的标题, 假设文件名为file.md,下面是示例代码,其唯一目的是匹配缺少空行的标题

$FileData = Get-Content file.md

if ($FileData -match '(?m)^#+\s.*$\s*^.+') { $Matches }

预期输出

## DESCRIPTION
### EXAMPLE 1
## OUTPUTS

实际输出

<no output>

其他正则表达式尝试如下,但均无效:

(?m)^#+\s.*\n*^.+
(?m)^#+\s.*\r\n*^.+
^#+\s.*$(?=\n^.+)
^#+\s.*$(?=\r\n^.+)
^#+\s.*$(?=\s^.+)

没有匹配的东西,这些正则表达式应该能够正常工作,因为只需对VSCode进行少量修改,它们就可以正常工作,但不能在PowerShell中运行,例如:

^#+\s.*$(?=\n^.+)对于VSCode引擎来说工作得很好,\n用于VSCode,但是在PowerShell (?m)中应该使用\r\n\n,但不能使用这些构造中的一个有效。

我确定有人对此有答案,但是请在您的答案中包括为什么(?m)\r\n都不起作用以及在这种特定情况下如何同时使用它们的原因?

编辑:

根据Wiktor的评论,我尝试了他的建议,但并没有给我想要的结果:

$FileData = Get-Content file.md -Raw

foreach ($Line in $FileData) {
if ($Line -match '^#+\s.*$(?=\s^.+)') { $Matches }  
}

我尝试了此处发布的所有示例正则表达式,但输出错误或所有输出均不输出

解决方法

您需要确保将整个文件作为一个变量发送给regex usign -Raw选项。

然后,您需要确保图案可以在多行模式下使用,可以使用

(?m)^#+[\p{Zs}\t].*$(?=\n.)

请参见regex demo

  • (?m)-现在,^匹配行的开头,$匹配行的结尾
  • ^-一行的开头
  • #+-一个或多个#字符
  • [\p{Zs}\t]-任何水平空格
  • .*-除换行符/换行符外的任何零个或多个字符
  • $-行尾(在换行符之前的位置)
  • (?=\n.)-一个正向的超前查询,可确保在当前位置的右边有一个换行符和除换行符以外的任何字符。

在Powershell中,您可以使用

 Get-Content 'c:\1\1.txt' -Raw | Select-String '(?m)^#+[\p{Zs}\t].*$(?=\n.)' -AllMatches | Foreach {$_.Matches} | Foreach-Object {$_.Value}