PowerShell 中的多行正则表达式匹配有或没有前瞻
Multiline regex match in PowerShell with or without lookahead
我正在尝试格式化 markdown 文件,以便在标题后有一个空行,该文件是 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>
其他正则表达式尝试如下,但 none 有效:
(?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
但这些构造中的 none 有效。
我确定有人对此有答案,但请在你的答案中说明为什么 (?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]
- 任何水平空格
.*
- newline/line feed 以外的任何零个或多个字符
$
- 行尾(换行符之前的位置)
(?=\n.)
- 确保在当前位置右侧立即有换行符和换行符以外的任何字符的正向前瞻。
在 Powershell 中,您可以使用
Get-Content 'c:.txt' -Raw | Select-String '(?m)^#+[\p{Zs}\t].*$(?=\n.)' -AllMatches | Foreach {$_.Matches} | Foreach-Object {$_.Value}
我正在尝试格式化 markdown 文件,以便在标题后有一个空行,该文件是 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>
其他正则表达式尝试如下,但 none 有效:
(?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
但这些构造中的 none 有效。
我确定有人对此有答案,但请在你的答案中说明为什么 (?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]
- 任何水平空格.*
- newline/line feed 以外的任何零个或多个字符
$
- 行尾(换行符之前的位置)(?=\n.)
- 确保在当前位置右侧立即有换行符和换行符以外的任何字符的正向前瞻。
在 Powershell 中,您可以使用
Get-Content 'c:.txt' -Raw | Select-String '(?m)^#+[\p{Zs}\t].*$(?=\n.)' -AllMatches | Foreach {$_.Matches} | Foreach-Object {$_.Value}