我正在尝试获取第一块发行说明...
(请参阅代码中的示例内容)
每当我使用一些简单的东西时,
它只会在我尝试跨多行 ( \n
)搜索时中断。
我正在使用,(Get-Content $changelog | Out-String)
因为它返回 1 个字符串而不是每行的数组。
$changelog = 'C:\Source\VSTS\AcmeLab\AcmeLab Core\changelog.md'
$regex = '([Vv][0-9]+\.[0-9]+\.[0-9]+\n)(^-.*$\n)+'
(Get-Content $changelog | Out-String) | Select-String -Pattern $regex -AllMatches
<#
SAMPLE:
------
v1.0.23
- Adds an IContainer API.
- Bugfixes.
v1.0.22
- Hotfix: Language operators.
v1.0.21
- Support duplicate query parameters.
v1.0.20
- Splitting up the ICommand interface.
- Fixing the referrer header empty field value.
#>
Run Code Online (Sandbox Code Playgroud)
我需要的结果是:
v1.0.23
- Adds an IContainer API.
- Bugfixes.
Run Code Online (Sandbox Code Playgroud)
更新:
使用选项..
$changelog = 'C:\Source\VSTS\AcmeLab\AcmeLab Core\changelog.md'
$regex = '(?smi)([Vv][0-9]+\.[0-9]+\.[0-9]+\n)(^-.*$\n)+'
Get-Content -Path $changelog -Raw | Select-String -Pattern $regex -AllMatches
Run Code Online (Sandbox Code Playgroud)
我也一无所获..(无论我使用\n
或\r\n
)
Get-Content -Raw
将整个文件作为单个字符串读取会更简单、更有效;此外,Out-String
向字符串添加一个额外的换行符。[1]-match
运算符 - 无需Select-String
's-AllMatches
开关。
Select-String
不使用它,但使用-match
运算符会更有效,因为您已经将整个文件读入内存。因此,以下返回第一个块(如果有):
if ((Get-Content -Raw $changelog) -match '(?m)^v\d+\.\d+\.\d+.*(\r?\n-\s?.*)+') {
# Match found - output it.
$Matches[0]
}
Run Code Online (Sandbox Code Playgroud)
*(?m)
打开内联正则表达式选项m
(多行),这会导致锚点^
并$
匹配各个行的开头和结尾,而不是整个字符串的开头和结尾。
\r?\n
匹配 CRLF 和仅 LF 换行符。(...)
子表达式非捕获,因为你不是在它捕获感兴趣的是:(?:...)
。请注意,-match
它本身返回一个布尔值(带有标量 LHS),但有关匹配的信息记录在自动$Matches
哈希表变量中,其0
条目包含整体匹配。
至于你尝试了什么:
'([Vv][0-9]+\.[0-9]+\.[0-9]+\n)(^-.*$\n)+'
Run Code Online (Sandbox Code Playgroud)
不起作用,因为默认情况下$
仅匹配输入字符串的最末尾,最后一行的末尾(尽管可能在最后一个换行符之前)。为了$
匹配每一行的结尾,你必须打开多行正则表达式选项(你在第二次尝试中做了)。结果,没有任何匹配。
'(?smi)([Vv][0-9]+\.[0-9]+\.[0-9]+\n)(^-.*$\n)+'
Run Code Online (Sandbox Code Playgroud)
不能按预期工作,因为通过使用选项s
(单行),您也.
匹配了换行符,因此贪婪的子表达式(例如).*
将匹配字符串的其余部分,跨行。结果,从第一个块开始的所有内容都匹配。
[1] GitHub 问题 #14444 中讨论了这种有问题的行为。
归档时间: |
|
查看次数: |
2082 次 |
最近记录: |