Home > Blockchain >  PowerShell regex/map not finding pattern(s) for right side (value)
PowerShell regex/map not finding pattern(s) for right side (value)

Time:12-22

I have a PowerShell 5.1 script that is mapping key/value pairs for file contents. I am finding the key, but the value isn't finding, and I'm having trouble getting it to find the values.

I tried using regex101.com to test different designs. I'd appreciate any help. This is my mapping function so far:

#returns map of CommNumMapping
function Get-CommNumMapping { 
  param([string]$commNumContents)
  Process{
  # create hashtable to hold the final mappings
  $errorMap = @{}
  # create array to collect keys that are grouped together
  $keys = @()

  switch -Regex ($commNumContents -split '\r?\n') {  #test regex with https://regex101.com/
    'define\s(\w )' { 
        # add relevant key to key collection
        $keys = $Matches[1] } #only match once
    'define\s[\w ]*[\s]*([\w]*)*' { 
        # we've reached the relevant error, set it for all relevant keys
        foreach($key in $keys){
            #Write-Host "alarm id def key: $key"
            $errorMap[$key] = $Matches[1]
        }
    }
    'break' {
        # reset/clear key collection
        $keys = @()
    }    
  }
  Write-Host "error map: $($errorMap)"
  Write-Host "alarm id def error map: $($errorMap['keyHere'])"
  return $errorMap
  }
}

#main code###############################
...
$comm_num_map = Get-CommNumMapping $commNumContents

Where $commNumContents is like this:

#define COM_ERROR_BASE                              1

////////////////////////////////////////////////////////////////////////////////////////
// COM Import error codes

//Definitions of error codes 
#define COMIMPORT_ERROR_BASE                        COM_ERROR_BASE   10
#define DC_ERROR_BASE                               COM_ERROR_BASE   500
#define DC_ERROR_INI_FILE                           DC_ERROR_BASE
#define DC_ERROR_SETPATH                            DC_ERROR_BASE   20
...

I'm having trouble finding a regex that will capture the entire part after the key part on the left. I will parse the Map Value's (left and right) parts later for the right part (COM_ERROR_BASE 10) after the map is obtained, for further evaluation.

I'd appreciate any help on this! I've got the Value to locate the first word (ex. COM_ERROR_BASE) ok sometimes, but every time I try to get it to get the rest, I lose what I had so far for the Map Value. I'd rather stick with this Mapping Function format, since I have another 4 of them and it's better to stay with similar flow. I need help with the regex in the Mapping function to obtain the Values.

Update: This is close for the Value regex, but it's not capturing the first line where ComErrorBase is 1. It gets the other ones

define\s[\w ]*[\s]*?([\s\w]*[ ][\s\w]*)*

CodePudding user response:

You probably want 'define\s \w \s (. )\s*' in order to capture everything starting with the 2nd word after the define keyword (excluding trailing whitespace), such as
COM_ERROR_BASE 10

The reason that your attempt didn't work was that ([\w]*)* captures an empty string, due to the trailing * duplication symbol (leaving aside that \w wouldn't match spaces and a literal ).

To demonstrate the problem:

# Even just removing the trailing * would help.
# However, to capture a *nonempty* word, use \w 
PS> if ('foo' -match '(\w*)*') { '[{0}]' -f $Matches.1 }
[]
  • Related