【问题标题】:Powershell Regex confusionPowershell 正则表达式混淆
【发布时间】:2018-07-05 10:52:38
【问题描述】:

目标字符串:

8AM - 10AM (local time)
12PM - 1PM (local time)

我可以用这个表达式从https://regexr.com/ 中提取时间:

\d{1,2}(AM|PM)

但是,我无法在 powershell 中这样做:

cls
$var = "8AM - 10AM (local time)
12PM - 1PM (local time)"
if ($var -match "\d{1,2}(AM|PM)")
{
    $matches
}

PS 输出:

Name    Value                                                                                                                                                                                                            
----    -----                                                                                                                                                                                                            
1       AM                                                                                                                                                                                                               
0       8AM       

但是,当我在 PS 中使用下面的脚本时:

cls
$var = "8AM - 10AM (local time)"
[regex]::Matches($var,"\d{1,2}(AM|PM)").Value

它给出了正确的输出:

8AM
10AM

关于为什么会发生这种情况的任何想法?

【问题讨论】:

标签: regex powershell powershell-3.0


【解决方案1】:
  • -match 运算符最多只能查找 1 个匹配项。

    • 如果您需要多个匹配项,[regex]::Matches() 确实是正确的选择。
    • 或者,使用Select-String cmdlet,但是会慢得多:
      ('8AM - 10AM (local time)' | Select-String -AllMatches '\d{1,2}(AM|PM)').Matches.Value
  • 因此,对于-match,自动$Matches 结果变量只包含有关该1 个匹配项的信息,可能包括capture-group 个匹配项。

    • 您的正则表达式的(AM|PM) 部分是一个捕获组,因此对于第一个整体匹配 - 8AM - 捕获组的结果是AM。
    • $Matches 是一个[hashtable],其带有0 键的条目包含整体匹配;条目 <n> 包含第 n 个(未命名的)捕获组结果。
    • 由于枚举 [hashtable] 的条目没有保证的顺序,因此在这种情况下,1 条目恰好列在 0 条目之前。

【讨论】:

    猜你喜欢
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多