0

I'm trying to loop through an array of alarm codes and use a regular expression to look it up in cpp code. I know my regex works when I hard code a value in and use double quotes for my regex, but I need to pass in a variable because it's a list of about 100 to look up with separate definitions. Below is what I want to use in general. How do I fix it so it works with $lookupItem instead of hard-coding "OTHER-ERROR" for example in the Get-EpxAlarm function? I tried single quotes and double quotes around $lookupItem in the $fullregex definition, and it returns nothing.

Function Get-EpxAlarm{
  [cmdletbinding()]
  Param ( [string]$fileContentsToParse, [string]$lookupItem)
  Process
  {
     $lookupItem = "OTHER_ERROR"
     Write-Host "In epx Alarm" -ForegroundColor Cyan

     # construct regex
     $fullregex = [regex]'$lookupItem', # Start of error message########variable needed
     ":[\s\Sa-zA-Z]*?=",             # match anything, non-greedy
     "(?<epxAlarm>[\sa-zA-Z_0-9]*)", # Capture epxAlarm Num
     '' -join ''
    
     # run the regex
     $Values = $fileContentsToParse | Select-String -Pattern $fullregex -AllMatches

     # Convert Name-Value pairs to object properties
     $result = $Values.Matches
     Write-Host $result

     #Write-Host "result:" $result -ForegroundColor Green

     return $result
  }#process
}#function


#main code

    ...
    Get-EpxAlarm -fileContentsToParse $epxContents -lookupItem $item
    ...

where $fileContentsToParse is

        case OTHER_ERROR:
            bstrEpxErrorNum = FATAL_ERROR;
            break;

        case RI_FAILED:
        case FILE_FAILED:
        case COMMUNICATION_FAILURE:
            bstrEpxErrorNum = RENDERING_ERROR;
            break;

So if I look for OTHER_ERROR, it should return FATAL_ERROR.

I tested my regular expression in regex editor and it works with the hard-coded value. How can I define my regex so that I use the parameter and it returns the same thing as hard-coding the parameter value?

3
  • @SantiagoSquarzon like I said in the writeup, I tried double quotes and it's not working like hard-coding does. It returns nothing. Commented Dec 17, 2021 at 15:42
  • 1
    You're right, my bad, I tested it using "OTHER_ERROR" and it worked for me but then "RI_FAILED" did not work. Commented Dec 17, 2021 at 16:04
  • you could use an ArgumentCompleter for the cases that would be pretty cool Commented Dec 17, 2021 at 16:10

1 Answer 1

1

I wouldn't recommend trying to construct a single regular expression to do complex source code parsing - it gets quite unreadable really quickly.

Instead, write a small error mapping parser that just reads the source code line by line and constructs the error mapping table as it goes along:

function Get-EpxErrorMapping {
  param([string]$EPXFileContents)

  # create hashtable to hold the final mappings
  $errorMap = @{}
  # create array to collect keys that are grouped together
  $keys = @()

  switch -Regex ($EPXFileContents -split '\r?\n') {
    'case (\w+):' {
        # add relevant key to key collection
        $keys += $Matches[1] }
    'bstrEpxErrorNum = (\w+);' {
        # we've reached the relevant error, set it for all relevant keys
        foreach($key in $keys){
            $errorMap[$key] = $Matches[1]
        }
    }
    'break' {
        # reset/clear key collection
        $keys = @()
    }    
  }

  return $errorMap
}

Now all you need to do is call this function and use the resulting table to resolve the $lookupItem value:

Function Get-EpxAlarm{
  [CmdletBinding()]
  param(
    [string]$fileContentsToParse,
    [string]$lookupItem
  )

  $errorMap = Get-EpxErrorMapping $fileContentsToParse

  return $errorMap[$lookupItem]
}

Now we can get the corresponding error code:

$epxContents = @'
case OTHER_ERROR:
    bstrEpxErrorNum = FATAL_ERROR;
    break;

case RI_FAILED:
case FILE_FAILED:
case COMMUNICATION_FAILURE:
    bstrEpxErrorNum = RENDERING_ERROR;
    break;
'@

# this will now return the string "FATAL_ERROR"
Get-EpxAlarm -fileContentsToParse $epxContents -lookupItem OTHER_ERROR
Sign up to request clarification or add additional context in comments.

13 Comments

It's not working for me. When I Write-Host "found it: $errorMap[$lookupItem]", it prints this: found it: System.Collections.Hashtable[ HOP_PRT_NO_MEMORY]. Also, Write-Host $errorMap prints nothing.
You need Write-Host "found it: $($errorMap[$lookupItem])". Thanks @SantiagoSquarzon, fixed
I tried the Write-Host "found it: $(...)" and it still prints nothing after found it
@SantiagoSquarzon It's printing hashtable contents now! Thanks!
@Michele You can remove leading and trailing spaces with $lookupItem.Trim() (so, Write-Host "error map: $($errorMap[$lookupItem.Trim()])").
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.