0

I have been using regex to parse text within some XML nodes. However, when I use -SimpleMatch with Select-String, the MatchInfo object doesn't appear to contain any matches.

I am unable to find anything online that indicates this behavior is normal. I am now wondering if it is my Powershell installation. (For reference: the computer I'm using has Powershell 3.0 installed.)

Using a very simple example, we can return the expected MatchInfo Object when using the regex patterning:

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

But adding the -SimpleMatch parameter appears to not return the Matches property in the MatchInfo object:

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

PS H:\> $c.Matches

PS H:\>

Piping $c to Get-Member confirms a MatchInfo Object was returned:

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;}                                        

And other properties, such as Pattern and Line work:

PS H:\> $c.Pattern
ab

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

Also, no error is generated when sending an index value to the Matches array:

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

PS H:\> 

I am not certain how to interpret the results, nor am I certain why it is occuring.

This behavior is problematic, as there are many times I must search for strings that contain regex special characters, ()'s are very common.

Expanding on the example:

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

PS H:\> $c.Matches

PS H:\> 

$c.Matches returns nothing, and $c itself is null, due to the use of the parentheses in the regex pattern:

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

Using -SimpleMatch does produce a MatchInfo object, but still does not return any matches:

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:\> 

The work-around I found (here on SO) is to use the Regex.Escape method from .NET:
(reference: 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)

As this workaround returns the expected matches from Select-String, I have been able to continue my scripting.

But I am curious as to why no matches are returned when using the -SimpleMatch parameter.

...
With regards,
Schwert

Community
  • 1
  • 1
  • `System.Text.RegularExpressions.Match` is regular expression object, so if you does not use regular expression, then you does not get `Match` object. – user4003407 Oct 16 '15 at 21:29
  • @PetSerAl: I had not piped the `Matches` object to `Get-Member` before now. Doing so does indicate `System.Text.RegularExpressions.Match` as the typename. – Schwert im Stein Oct 19 '15 at 12:34

1 Answers1

2

From Get-Help Select-String -Parameter SimpleMatch:

-SimpleMatch [<SwitchParameter>]

Uses a simple match rather than a regular expression match. In a simple match, Select-String searches the input for the text in the Pattern parameter. It does not interpret the value of the Pattern parameter as a regular expression statement.

So, SimpleMatch simply does a substring search for $Pattern inside each string you pipe to it. It returns a MatchInfo object containing the string and relevant contextual information if present, but no Matches since a proper regex matching was never carried out against the string - it's as simple as that

Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
  • I looked much more closely at the `MatchInfo` information on the Microsoft Developer Network, specifically at the 'Match' Class, and found the following: _"Represents the results from a single regular expression match."_ It is not the most obvious place to put it, but I suppose the `Matches` object is not necessary with `SimpleMatch`, as it should just be the original search string. – Schwert im Stein Oct 19 '15 at 12:38
  • @SchwertimStein The [msdn article for `MatchInfo`](https://msdn.microsoft.com/en-us/library/microsoft.powershell.commands.matchinfo(v=vs.85).aspx) clearly states: *"This object is returned by the Select-String cmdlet. It provides information about the results of a match."* - it doesn't allude to whether that be a regex-based match or a simple match – Mathias R. Jessen Oct 19 '15 at 12:42
  • I should have added a link for the page I was referencing: [the Match Class article on MSDN](https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.match(v=vs.85).aspx) @PetSerAl made a comment about how the `Matches` part of the `MatchInfo` object is of the type `System.Text.RegularExpressions.Match`. In order to better understand his comment, I found the Match Class article I referenced above. My comment about the `Matches` part is my thought that if `Matches` contained a value with `SimpleMatch`, it would be the original search string. So, there is nothing in `Matches`. – Schwert im Stein Oct 19 '15 at 13:15