'PowerShell regex to get just hex part in strings

I'm working on a function that gets the map of string key and it's hex value. I got the string key part working, but I'm having trouble getting the hex part to work. This is my function so far:

function Get-Contents4_h{
  [cmdletbinding()]
  Param ([string]$fileContent) 

          #define Error_Failed_To_Do_A          0x81A0  /* random comments */
          #define Error_Failed_To_Do_B      0x810A

  # create an ordered hashtable to store the results
  $errorMap = [ordered]@{}
  # process the lines one-by-one
  switch -Regex ($fileContent -split '\r?\n') {
      'define ([\w]*)' { # Error_Failed_To_Do_  #this works fine
          $key = ($matches[1]).Trim()
      }
      '([0x\w]*)' {  # 0x04A etc #this does not work
          $errorMap[$key] = ($matches[1]).Trim()
      }
  }
  # output the completed data as object
  #[PsCustomObject]$errorMap
  return $errorMap
}

I'm going to be looping through the returned map and matching the hex value with the key in another object.

This is what the string parameter to the function looks like:

#define Error_Failed_To_Do_A            0x81A0  /* random comments */
#define Error_Failed_To_Do_B        0x810A

For some reason my

0x\w

regex is not returning anything in regex101.com. I've had luck with that with other hex numbers but not this time.

I've tried this and other variations as well: ^[\s\S]*?#[\w]*[\s\S]+([0x\w]*)

This is with powershell 5.1 and VS Code.



Solution 1:[1]

You need to remove the [...] range construct around 0x\w - the 0x occurs exactly once in the input string, and the following characters appears at least once - but the expression [0x\w]* could be satisfied by an empty string (thanks to the *, 0-or-more quantifier).

I'd suggest matching the whole line at once with a single pattern instead:

switch -Regex ($fileContent -split '\r?\n') {
    '^\s*#define\s+(\w+)\s+(0x\w+)' {
        $key,$value = $Matches[1,2] |ForEach-Object Trim          
        $errorMap[$key] = $value
    }
}

Solution 2:[2]

This works for me. The square brackets match any one character inside them at a time. The pattern with the square brackets has 18 matches in this line, the first match being empty string ''. Regex101.com says the same thing (null). https://regex101.com/r/PZ8Y8C/1 This would work 0x[\w]*, but then you might as well drop the brackets. I made an example data file and then a script on how I would do it.

'#define Error_Failed_To_Do_A 0x81A0  /* random comments */' | 
  select-string [0x\w]* -AllMatches | % matches | measure | % count

18
'#define Error_Failed_To_Do_A            0x81A0  /* random comments */
#define Error_Failed_To_Do_B        0x810A' | 
set-content file.txt
# Get-Contents4_h.ps1

Param ($file)

switch -Regex -File $file {
    'define (\w+).*(0x\w+)' {
      [pscustomobject]@{
        Error = $matches[1]
        Hex = $matches[2]
      }
    }
}
.\Get-Contents4_h file.txt

Error                Hex
-----                ---
Error_Failed_To_Do_A 0x81A0
Error_Failed_To_Do_B 0x810A

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mathias R. Jessen
Solution 2