【问题标题】:Matches not captured when using -SimpleMatch with Select-String将 -SimpleMatch 与 Select-String 一起使用时未捕获匹配项
【发布时间】:2015-10-16 21:20:50
【问题描述】:

我一直在使用正则表达式来解析一些 XML 节点中的文本。但是,当我使用 -SimpleMatchSelect-String 时,MatchInfo 对象似乎不包含任何匹配项。

我无法在网上找到任何表明此行为正常的信息。我现在想知道这是否是我的 Powershell 安装。 (供参考:我使用的计算机已安装 Powershell 3.0。)

使用一个非常简单的示例,我们可以在使用正则表达式模式时返回预期的 MatchInfo 对象:

PS H:\> $c = "abd 14e 568" | Select-String -Pattern "ab"

PS H:\> $c.Matches


Groups   : {ab}
Success  : True
Captures : {ab}
Index    : 0
Length   : 2
Value    : ab

但添加 -SimpleMatch 参数似乎不会返回 MatchInfo 对象中的 Matches 属性:

PS H:\> $c = "abd 14e 568" | Select-String -Pattern "ab" -SimpleMatch

PS H:\> $c.Matches

PS H:\>

$c 连接到Get-Member 确认返回了一个 MatchInfo 对象:

PS H:\> $c | gm


   TypeName: Microsoft.PowerShell.Commands.MatchInfo

Name         MemberType Definition                                                       
----         ---------- ----------                                                       
Equals       Method     bool Equals(System.Object obj)                                   
GetHashCode  Method     int GetHashCode()                                                
GetType      Method     type GetType()                                                   
RelativePath Method     string RelativePath(string directory)                            
ToString     Method     string ToString(), string ToString(string directory)             
Context      Property   Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename     Property   string Filename {get;}                                           
IgnoreCase   Property   bool IgnoreCase {get;set;}                                       
Line         Property   string Line {get;set;}                                           
LineNumber   Property   int LineNumber {get;set;}                                        
Matches      Property   System.Text.RegularExpressions.Match[] Matches {get;set;}        
Path         Property   string Path {get;set;}                                           
Pattern      Property   string Pattern {get;set;}                                        

还有其他属性,比如 Pattern 和 Line work:

PS H:\> $c.Pattern
ab

PS H:\> $c.Line
abd 14e 568

另外,将索引值发送到 Matches 数组时不会产生错误:

PS H:\> $c.Matches[0]

PS H:\> 

我不确定如何解释结果,也不确定为什么会发生。

这种行为是有问题的,因为很多时候我必须搜索包含正则表达式特殊字符的字符串,() 很常见。

扩展示例:

PS H:\> $c = "ab(d) 14e 568" | Select-String -Pattern "ab(d)"

PS H:\> $c.Matches

PS H:\> 

$c.Matches 不返回任何内容,并且$c 本身为空,因为在正则表达式模式中使用了括号:

PS H:\> $c -eq $null
True

使用-SimpleMatch 确实会产生一个 MatchInfo 对象,但仍然不会返回任何匹配项:

PS H:\> $c = "ab(d) 14e 568" | Select-String -Pattern "ab(d)" -SimpleMatch

PS H:\> $c -eq $null
False

PS H:\> $c.Matches

PS H:\> 

我发现的解决方法(在 SO 上)是使用 .NET 中的 Regex.Escape 方法:
(参考:Powershell select-string fails due to escape sequence

PS H:\> $pattern = "ab(d)"
$pattern = ([regex]::Escape($pattern))
$c = "ab(d) 14e 568" | Select-String -Pattern $pattern

PS H:\> $c.Matches


Groups   : {ab(d)}
Success  : True
Captures : {ab(d)}
Index    : 0
Length   : 5
Value    : ab(d)

由于此解决方法从 Select-String 返回预期的匹配项,因此我能够继续编写脚本。

但我很好奇为什么使用-SimpleMatch 参数时没有返回匹配项。

...
关于,
施韦特

【问题讨论】:

  • System.Text.RegularExpressions.Match 是正则表达式对象,所以如果不使用正则表达式,则不会得到Match 对象。
  • @PetSerAl:我之前没有将Matches 对象通过管道传输到Get-Member。这样做确实会将 System.Text.RegularExpressions.Match 指示为类型名。

标签: regex powershell escaping select-string


【解决方案1】:

来自Get-Help Select-String -Parameter SimpleMatch

-SimpleMatch [<SwitchParameter>]

使用简单匹配而不是正则表达式匹配。在简单匹配中,Select-String 在输入中搜索 Pattern 参数中的文本。 它不会将 Pattern 参数的值解释为正则表达式语句。

所以,SimpleMatch 只是在您通过管道传递给它的每个字符串中对$Pattern 进行子字符串搜索。它返回一个 MatchInfo 对象,其中包含字符串和相关的上下文信息(如果存在),但没有 Matches,因为从未对字符串执行正确的正则表达式匹配 - 就这么简单

【讨论】:

  • 我更仔细地查看了 Microsoft Developer Network 上的 MatchInfo 信息,特别是 'Match' 类,发现如下:"表示单个正则表达式的结果匹配。” 这不是最明显的放置位置,但我认为 SimpleMatch 不需要 Matches 对象,因为它应该只是原始搜索字符串。
  • @SchwertimStein msdn article for MatchInfo 明确指出:“此对象由 Select-String cmdlet 返回。它提供有关匹配结果的信息。” - 它没有'不暗示这是基于正则表达式的匹配还是简单的匹配
  • 我应该为我引用的页面添加一个链接:the Match Class article on MSDN @PetSerAl 评论了MatchInfo 对象的Matches 部分如何属于System.Text.RegularExpressions.Match 类型。为了更好地理解他的评论,我找到了我上面引用的 Match Class 文章。我对Matches 部分的评论是我认为如果Matches 包含SimpleMatch 的值,它将是原始搜索字符串。所以,Matches 里面什么都没有。
猜你喜欢
  • 2021-01-20
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 2023-03-23
  • 1970-01-01
相关资源
最近更新 更多