【问题标题】:Match across line breaks when using -match with a regular expression将 -match 与正则表达式一起使用时匹配换行符
【发布时间】:2021-12-02 07:46:09
【问题描述】:

以下结果为“foo”的单个匹配项。

$multilineString = "foo
    bar
         baz";

$multilineString -match ".*";

$matches;

那是因为the . character does not include line breaks

这些也只输出“foo”。

$multilineString -match "(.|\r)*" | Out-Null; $matches[0];
$multilineString -match "(.|\r\n)*" | Out-Null; $matches[0];

在 PowerShell 中,我们如何使用 match 来包含任何字符,包括换行符,以便输出包含所有三行:

foo
bar
baz

【问题讨论】:

  • 您需要使用(?ms).*。有关详细信息,请参阅this answer。如果您使用的是[regex]::Matches(...),则同样适用
  • 如果您只想匹配 3 个单词而无需修剪前导和尾随空格,您可以使用 [regex]::Matches($multilineString, '\w+').Value
  • @SantiagoSquarzon 感谢(?ms).* 的提示。此外,对于这个用例,我们使用 -match 运算符很重要。
  • 我不知道你将如何使用-mach 获得与[regex]::Matches($multilineString, '\w+').Value 相同的结果(包含3 个单词的数组),除非你对字符串执行-split '\r?\n' 然后循环遍历每个元素。

标签: windows powershell


【解决方案1】:

我几乎从不将-match 用于此特定用途,就像在我的评论中一样,我通常使用[regex]。查看 MS Docs 后:

请务必注意,$Matches 哈希表仅包含任何匹配模式的第一次出现。

因此,如果您想获得与[regex]::Matches($multilineString, '\w+').Value 相同的结果,则需要先拆分字符串,然后对其进行循环:

$multilineString = "foo
    bar
         baz"

$multilineString -split '\r?\n' | ForEach-Object {
    if($_ -match '\w+')
    {
        $Matches
    }   
}
Name                           Value
----                           -----
0                              foo
0                              bar
0                              baz

也可以使用不需要拆分或循环的替代方法,但regex 模式必须更具体。在这种情况下,我们知道我们正在寻找 3 个单词。

$multilineString = "foo
    bar
         baz"

$multilineString -match '^(\w+)\s+(\w+)\s+(\w+)$'
$Matches
Name                           Value
----                           -----
3                              baz
2                              bar
1                              foo
0                              foo…

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2021-12-14
    • 2014-06-30
    • 1970-01-01
    • 1970-01-01
    • 2016-02-16
    相关资源
    最近更新 更多