As you've observed, the automatic $Matches
variable, which reflects the result of the most recent (scalar-input[1]) regular-expression-based match
operation, only ever contains the last instance of what an embedded capture group ((...)
) captured.
Generally, -match
only ever looks for at most ONE match in the input.
- GitHub issue #7867 proposes introducing a new
-matchall
operator that would find all matches and return them as an array.
Direct use of the [regex]
class (System.Text.RegularExpressions.Regex
) that underlies PowerShell's regex functionality already provides that ability, namely in the form of the ::Matches()
method, in which case capture groups aren't even needed.
# Note: Inline option (?i) makes the regex case-INsensitive
# (which PowerShell's operators are BY DEFAULT).
PS> [regex]::Matches('708BCDBC8A0D', '(?i)[0-9a-f]{2}').Value
70
8B
CD
BC
8A
0D
However, with a bit of trickery, you can also use -split
, the string splitting operator:
# Note: No inline option needed: -split - like -match and -replace -
# is case-INsensitive by default.
PS> '708BCDBC8A0D' -split '([0-9a-f]{2})' -ne ''
70
8B
CD
BC
8A
0D
If can assume that all character pairs in the input strings are hex byte values, you can simplify to:
'708BCDBC8A0D' -split '(..)' -ne ''
Note:
The regex is of necessity enclosed in (...)
, a capturing group, to explicitly instruct -split
to include what it matches in the results; since the regex normally describes the separators between the substrings of interest, its matches are normally not included.
In this case it is only the "separators" we care about, whereas the substrings between them are empty strings here, so we filter them out with -ne ''
.
[1] If the LHS of a -match
operation is an array (a collection), matching occurs against each element, and the sub-array of matching elements (rather than a single Boolean) is returned. In this case, $Matches
is not populated.