Home > database >  using a partial variable as part of regular expression string
using a partial variable as part of regular expression string

Time:12-18

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?

CodePudding user response:

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
  • Related