Home > Mobile >  Parsing several groups out of repeated pattern returning False
Parsing several groups out of repeated pattern returning False

Time:12-16

I'm trying to parse several repeated groups out of a document (for each case statment, I need the number in the stprintf(ex. 8000), the description after it (ex. Comm Err 05 - Timeout sending command), and the severity (warning or fatal). For some reason result is empty. I looked at this match and nomatch and I think I'm doing what they are. Does anyone see my issue(s), or have any other suggestions?

#Function to get needed contents from case statements in $parsedCaseMethod provided
Function Get-CaseContents{
  [cmdletbinding()]
  Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
  Process
  {
     Write-Host "This is what I'm dealing with people" -ForegroundColor Green
     Write-Host $parsedCaseMethod
     #parse the case data out:
     #ex from code:
     #case kRESULT_STATUS_PPA_Comm_Timeout:     #_stprintf is parseLinesGroupIndicator              
     #  _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
     #  outError    = INVALID_PARAM;
     #  outSeverity = CCA_WARNING;
     $regex = [regex]"\((.*)\)" #sdkErr
     $severity = [regex]"[\s\S.=;]*outSeverity[\s\S]*=[\s\Sa-zA-Z]*_(a-zA-Z)*" #severity warning or error etc
     $parsedCaseMethod -match  '$parseLinesGroupIndicator[\s\S]*(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)'
     Write-Output "sdkErr:"
     $Matches.sdkErr
     Write-Output "sdkDesc:"
     $Matches.sdkDesc
     Write-Output "sdkSeverity:"
     $Matches.sdkSeverity
  }#End of Process
}#End of Function

#main code
...
#call method to get case info
Get-CaseContents -parsedCaseMethod $matchFound -parseLinesGroupIndicator "_stprintf" #need to get returned info back

An example of the $matchFound contents include:

...
case kRESULT_STATUS_Undefined_Opcode:                       
            _stprintf( outDevStr, _T("8004 - (Comm. Err 04) - %s(Undefined Opcode)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;

        case kRESULT_STATUS_Comm_Timeout:                       
            _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;

        case kRESULT_STATUS_TXD_Failed:                     
            _stprintf( outDevStr, _T("8006 - (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;
...

It's ok if the three found variables are in an array, so it's easier to return them from the function, but I'm not up to that point yet.

For the method print statement, it's showing the string contents like above, followed by the following empty output:

bool 
False
sdkErr:
sdkDesc:
sdkSeverity:

I would have expected it to ultimately return (I realize I don't have an array collecting this, but maybe the last group's info): sdkErr: 8004, sdkDesc: (Comm. Err 04) - %s(Undefined Opcode), sdkSeverity: Warning

sdkErr: 8005, sdkDesc: (Comm. Err 05) - %s(Timeout sending command), sdkSeverity: Warning

sdkErr: 8006, sdkDesc: (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.), sdkSeverity: Warning

This is PowerShell 5.1. If anyone has any suggestions, that would be much appreciated!

Update: I tried updating the input string so I know exactly what it's parsing, and it's only parsing one case statement. It's still returning nothing for sdkErr, and the other things it prints. it looks ok to me. I'm not sure what I'm missing. I was looking at backticks and decided I needed backticks etc in the substring I'm hard-coding because I was getting "input string was not in correct format" in my string I pulled out to test with. In the below change I'm re-defining the parameter to my smaller string for testing, and revised my regex for testing it, since what I had before didn't work.

#Function to get needed contents from case statements in $parsedCaseMethod provided
Function Get-CaseContents{
  [cmdletbinding()]
  Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
  Process
  {
     #Write-Host "This is what I'm dealing with people" -ForegroundColor Green
     #Write-Host $parsedCaseMethod
     #parse the case data out:
     #ex from code:
     #case kRESULT_STATUS_Comm_Timeout:     #_stprintf is parseLinesGroupIndicator              
     #  _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
     #  outError    = INVALID_PARAM;
     #  outSeverity = CCA_WARNING;
     $parseCaseMethod = "case kRESULT_STATUS_Comm_Timeout:              
       _stprintf( outDevStr, _T(`"8005 - (Comm. Err 05) - %s(Timeout sending command)`"), errorStr);
       outError = INVALID_PARAM;
       outSeverity  = CCA_WARNING;"
     $regexNum = [regex]"$parseLinesGroupIndicator[\s\S.]*_T[.*](0-9)*"
     $regex = [regex]"\((.*)\)" #sdkErr

     $severity = [regex]"[\s\S.=;]*outSeverity[\s\S]*=[\s\Sa-zA-Z]*_(a-zA-Z)*" #severity warning or error etc
     ##$parsedCaseMethod -match  "$parseLinesGroupIndicator[\s\S]*(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
     $parsedCaseMethod -match  "$regexNum(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
     Write-Output "sdkErr:"
     $Matches.sdkErr
     Write-Output "sdkDesc:"
     $Matches.sdkDesc
     Write-Output "sdkSeverity:"
     $Matches.sdkSeverity
  }#End of Process
}#End of Function 

Update2: I was playing around with a regex editor regex101.com and it's matching with what I'm showing for $regexNum, but for some reason it's not returning what I expect when I print $Matches.sdkErr. I'm not sure if I't sbecause the editor shows the 8000 part as a Group and there's a different way to obtain it. I tried $Matches.sdkErr.Group(1) but get this error with that

Method invocation failed because [System.String] does not contain a method named 'Group'.

This is the code change (most of the change is in $regexNum):

#Function to get needed contents from case statements in $parsedCaseMethod provided
Function Get-CaseContents{
  [cmdletbinding()]
  Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
  Process
  {
     #Write-Host "This is what I'm dealing with people" -ForegroundColor Green
     #Write-Host $parsedCaseMethod
     #parse the case data out:
     #ex from code:
     #case kRESULT_STATUS_PPA_Comm_Timeout:     #_stprintf is parseLinesGroupIndicator              
     #  _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
     #  outError    = INVALID_PARAM;
     #  outSeverity = CCA_WARNING;
     $parsedCaseMethod = "case kRESULT_STATUS_Comm_Timeout:             
       _stprintf( outDevStr, _T(`"8005 - (Comm. Err 05) - %s(Timeout sending command)`"), errorStr);
       outError = INVALID_PARAM;
       outSeverity  = CCA_WARNING;"
     ##$regexNum = [regex]"$parseLinesGroupIndicator[\s\Sa-zA-Z]*(0-9)*" 
     $regexNum = [regex]"$parseLinesGroupIndicator[\s\Sa-zA-Z]*_T[^[0-9]]*. ?([0-9][0-9]*)"
     # \s\S\(`",a-zA-Z.]*_T[.*](0-9)*
     $regex = [regex]"\((.*)\)" #sdkErr

     $severity = [regex]"[\s\S.=;]*outSeverity[\s\S]*=[\s\Sa-zA-Z]*_(a-zA-Z)*" #severity warning or error etc
     #$parsedCaseMethod -match  "$parseLinesGroupIndicator[\s\S]*(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
     #$parsedCaseMethod -match  "$regexNum(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
     $parsedCaseMethod -match  "(?<sdkErr>$regexNum)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
     Write-Output "sdkErr:"
     $Matches.sdkErr.Group(1)  #error message...with $Matches.sdkErr it prints entire Match and not just the part in parenthesis that I want (8000)
     Write-Output "sdkDesc:"
     $Matches.sdkDesc
     Write-Output "sdkSeverity:"
     $Matches.sdkSeverity
  }#End of Process
}#End of Function

I'm also looking at this string in text file

CodePudding user response:

You have some incorrect syntax in your regex, see notes below on suggested replacements. I also prefer using Select-String over -match as it can return multiple matches with -AllMatches:

# construct regex, previously done with variables
$fullregex = [regex]"_stprintf[\s\S]*?_T\D*", # Start of error message, capture until digits
    "(?<sdkErr>\d )",       # Error number, digits only
    "\D[\s\S]*?",           # match anything, non-greedy
    "(?<sdkDesc>\((.*)\))", # Error description, anything within parentheses
    "[\s\S]*?",             # match anything, non-greedy
    "(?<sdkSeverity>outSeverity\s*=\s[a-zA-Z_]*)", # Capture severity string
    '' -join ''

# run the regex
$Values = $parsedCaseMethod | Select-String -Pattern $fullregex -AllMatches

# Convert Name-Value pairs to object properties
$result = foreach ($match in $Values.Matches){
  [PSCustomObject][ordered]@{
    sdkErr      = $match.Groups['sdkErr']
    sdkDesc     = $match.Groups['sdkDesc']
    sdkSeverity = $match.Groups['sdkSeverity']
  }
}

$result
sdkErr sdkSeverity               sdkDesc                                                            
------ -----------               -------                                                            
8004   outSeverity = CCA_WARNING (Comm. Err 04) - %s(Undefined Opcode)"), errorStr)                 
8005   outSeverity = CCA_WARNING (Comm. Err 05) - %s(Timeout sending command)"), errorStr)          
8006   outSeverity = CCA_WARNING (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.)"), errorStr)

I made a bunch of assumptions about what you're looking for, but this may help

CodePudding user response:

I'm not quite sure if you want the output to be message strings or want the parsed info as array of objects, so below, it does both:

$matchFound = @"
case kRESULT_STATUS_Undefined_Opcode:                       
            _stprintf( outDevStr, _T("8004 - (Comm. Err 04) - %s(Undefined Opcode)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;

        case kRESULT_STATUS_Comm_Timeout:                       
            _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;

        case kRESULT_STATUS_TXD_Failed:                     
            _stprintf( outDevStr, _T("8006 - (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;
"@ -split '\r?\n'

$inCase = $false  # a flag telling us if we're inside a 'case' or not
$result = switch -Regex ($matchFound) {
    '^\s*case kRESULT' { 
        $inCase = $true 
        # create an object with for now null values in its properties
        $out = [PsCustomObject]@{ sdkErr = $nul; sdkDesc = $null; sdkSeverity = $null }
    }
    '^\s*_stprintf\(\s*outDevStr, _T\("(\d ) - (\(. \))"'  { 
        if ($inCase) {
            $out.sdkErr  = $matches[1]
            $out.sdkDesc = $matches[2]
        }
    }
    '^\s*outSeverity = (\w )' {
        if ($inCase) {
            $out.sdkSeverity = ($matches[1] -split '_')[-1]
            # now we have all info, output a string to the console
            Write-Host ('sdkErr: {0}, sdkDesc: {1}, sdkSeverity: {2}' -f $out.sdkErr, $out.sdkDesc, $out.sdkSeverity)
            # and output the completed object to be collected in $result
            $out
            # reset the flag so we can rebuild the object for the next 'case kRESULT'
            $inCase = $false
        }
    }
}

Output written on screen:

sdkErr: 8004, sdkDesc: (Comm. Err 04) - %s(Undefined Opcode), sdkSeverity: WARNING
sdkErr: 8005, sdkDesc: (Comm. Err 05) - %s(Timeout sending command), sdkSeverity: WARNING
sdkErr: 8006, sdkDesc: (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.), sdkSeverity: WARNING

Output as captured in variable $result:

$result | Format-Table -AutoSize
sdkErr sdkDesc                                                sdkSeverity
------ -------                                                -----------
8004   (Comm. Err 04) - %s(Undefined Opcode)                  WARNING    
8005   (Comm. Err 05) - %s(Timeout sending command)           WARNING    
8006   (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.) WARNING
  • Related