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 }
[]