Regex: Help with matches and capturing

Tagged: ,

This topic contains 2 replies, has 2 voices, and was last updated by Profile photo of Tony Pagliaro Tony Pagliaro 3 months, 2 weeks ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #42583
    Profile photo of Tony Pagliaro
    Tony Pagliaro
    Participant

    Hi All,
    Happy Friday, no rush on this one.. 🙂

    I've always had trouble understanding how to utilize regex matching in PS. Does the match return a boolean, or a string? Sometimes both depending on the time of day? ¯\_(ツ)_/¯

    Here's a good example, I can pull text from a backup job property and try to grab the 3 different numbers from it for use in a report. There might be better ways of accomplishing this, but I really want to understand how this $matches variable should work.

    $DSVerbiage = '
    30 generations
    If files are removed from source after 30 days, keep only 0 generations
    online.
    '
    
    [string]$LiveItemGenerationsPattern = '(\d{1,8})\sgeneration[s]?\sIf' 
    [int]$LiveItemGenerations = $DSVerbiage -match $LiveItemGenerationsPattern | %{$Matches.Values[0]}         # should be 30
    
    [string]$DeletedItemRetentionPattern = '(\d{1,8})\sdays, keep'
    [int]$DeletedItemRetention = $DSVerbiage -match $DeletedItemRetentionPattern | %{$Matches.Values[0]}       # should be 30
    
    [string]$DeletedItemGenerationsPattern = 'only\s(\d{1,12})\sgeneration'
    [int]$DeletedItemGenerations = $DSVerbiage -match $DeletedItemGenerationsPattern | %{$Matches.Values[0]}   # should be 0
    
    # FYI- I used regex101.com to test the patterns
    

    When I was building this, the first pattern returned 30, as it should have.

    PS> $DSVerbiage -match $LiveItemGenerationsPattern | %{$Matches.Values[0]} 
    30
    

    Then I tried the second. It didn't work. Then I tried the first again, it no longer worked.

    PS> $DSVerbiage -match $DeletedItemRetentionPattern | %{$Matches.Values[0]} 
    PS> 
    PS> $DSVerbiage -match $DeletedItemRetentionPattern | %{$Matches.Values[0]} 
    30
    30 days, keep
    PS> $DSVerbiage -match $DeletedItemRetentionPattern 
    True
    PS> $DSVerbiage -match $LiveItemGenerationsPattern 
    False
    PS>
    

    Weird right? I always see this when I play around with Regex, get frustrated, then find some other way to do it. Right now I'm thinking about getting into the backup application's DB to pull out the numbers directly. I also know that Regex is something that should be used when no other solution can get me to my goal, but I REALLY want to understand how these matches work.

    Also FYI:

    PS H:\> $PSVersionTable
    Name Value
    —- —–
    PSVersion 4.0
    WSManStackVersion 3.0
    SerializationVersion 1.1.0.1
    CLRVersion 4.0.30319.34209
    BuildVersion 6.3.9600.16406
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
    PSRemotingProtocolVersion 2.2

    #42609
    Profile photo of Curtis Smith
    Curtis Smith
    Participant

    Hey Tony,
    There are many ways to do Regex in Powershell, but below I will try to help explain how the -match operator works

    When you use -match, the operation returns a true or false Boolean value indicating whether the Regex pattern provided matched the string.

    $DSVerbiage = '
    30 generations
    If files are removed from source after 30 days, keep only 0 generations
    online.
    '
    
    $LiveItemGenerationsPattern = '(\d{1,8})\sgeneration[s]?\sIf'
    $LiveItemGenerations = $DSVerbiage -match $LiveItemGenerationsPattern
    $LiveItemGenerations
    

    Results:

    True
    

    At the same time, the $matches automatic variable is populated with a hashtable containing the regex matches

    Get-Member -InputObject $Matches
    $Matches
    

    Results:

       TypeName: System.Collections.Hashtable
    
    Name              MemberType            Definition                                                                                                                                                                                                               
    ----              ----------            ----------                                                                                                                                                                                                               
    Add               Method                void Add(System.Object key, System.Object value), void IDictionary.Add(System.Object key, System.Object value)                                                                                                           
    Clear             Method                void Clear(), void IDictionary.Clear()                                                                                                                                                                                   
    Clone             Method                System.Object Clone(), System.Object ICloneable.Clone()                                                                                                                                                                  
    Contains          Method                bool Contains(System.Object key), bool IDictionary.Contains(System.Object key)                                                                                                                                           
    ContainsKey       Method                bool ContainsKey(System.Object key)                                                                                                                                                                                      
    ContainsValue     Method                bool ContainsValue(System.Object value)                                                                                                                                                                                  
    CopyTo            Method                void CopyTo(array array, int arrayIndex), void ICollection.CopyTo(array array, int index)                                                                                                                                
    Equals            Method                bool Equals(System.Object obj)                                                                                                                                                                                           
    GetEnumerator     Method                System.Collections.IDictionaryEnumerator GetEnumerator(), System.Collections.IDictionaryEnumerator IDictionary.GetEnumerator(), System.Collections.IEnumerator IEnumerable.GetEnumerator()                               
    GetHashCode       Method                int GetHashCode()                                                                                                                                                                                                        
    GetObjectData     Method                void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context), void ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, ...
    GetType           Method                type GetType()                                                                                                                                                                                                           
    OnDeserialization Method                void OnDeserialization(System.Object sender), void IDeserializationCallback.OnDeserialization(System.Object sender)                                                                                                      
    Remove            Method                void Remove(System.Object key), void IDictionary.Remove(System.Object key)                                                                                                                                               
    ToString          Method                string ToString()                                                                                                                                                                                                        
    Item              ParameterizedProperty System.Object Item(System.Object key) {get;set;}                                                                                                                                                                         
    Count             Property              int Count {get;}                                                                                                                                                                                                         
    IsFixedSize       Property              bool IsFixedSize {get;}                                                                                                                                                                                                  
    IsReadOnly        Property              bool IsReadOnly {get;}                                                                                                                                                                                                   
    IsSynchronized    Property              bool IsSynchronized {get;}                                                                                                                                                                                               
    Keys              Property              System.Collections.ICollection Keys {get;}                                                                                                                                                                               
    SyncRoot          Property              System.Object SyncRoot {get;}                                                                                                                                                                                            
    Values            Property              System.Collections.ICollection Values {get;}                                                                                                                                                                             
    
    Key   : 1
    Value : 30
    Name  : 1
    
    
    Key   : 0
    Value : 30 generations
            If
    Name  : 0
    

    Likewise for your Second Pattern match

    $DSVerbiage = '
    30 generations
    If files are removed from source after 30 days, keep only 0 generations
    online.
    '
    
    $DeletedItemRetentionPattern = '(\d{1,8})\sdays, keep'
    $DeletedItemRetention = $DSVerbiage -match $DeletedItemRetentionPattern
    
    $DeletedItemRetention
    $Matches
    

    Results:

    True
    
    Name                           Value
    ----                           -----
    1                              30
    0                              30 days, keep
    

    As well as your third pattern

    $DSVerbiage = '
    30 generations
    If files are removed from source after 30 days, keep only 0 generations
    online.
    '
    $DeletedItemGenerationsPattern = 'only\s(\d{1,12})\sgeneration'
    $DeletedItemGenerations = $DSVerbiage -match $DeletedItemGenerationsPattern
    
    $DeletedItemRetention
    $Matches
    

    Results:

    True
    
    Name                           Value
    ----                           -----
    1                              0
                                  only 0 generation
    

    You should be able to see the pattern here. The value you are looking for is the second value in the resulting hashtable. So you can those values accordingly

    $DSVerbiage = '
    30 generations
    If files are removed from source after 30 days, keep only 0 generations
    online.
    '
    
    $LiveItemGenerationsPattern = '(\d{1,8})\sgeneration[s]?\sIf'
    $LiveItemGenerations = $DSVerbiage -match $LiveItemGenerationsPattern
    
    $Matches[1]
    
    $DeletedItemRetentionPattern = '(\d{1,8})\sdays, keep'
    $DeletedItemRetention = $DSVerbiage -match $DeletedItemRetentionPattern
    
    $Matches[1]
    
    $DeletedItemGenerationsPattern = 'only\s(\d{1,12})\sgeneration'
    $DeletedItemGenerations = $DSVerbiage -match $DeletedItemGenerationsPattern
    
    $Matches[1]
    

    Results:

    30
    30
    0
    
    #42666
    Profile photo of Tony Pagliaro
    Tony Pagliaro
    Participant

    Yes! Thank you! The elusive hash table strikes again.

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.