1

I am confused on how to get the number in the string below. I crafted a regex

$regex = '(?s)^.+\bTotal Members in Group: ([\d.]+).*$'

I need only the number part 2 inside a long string a line reads Total Members in Group: 2.

My $regex returns me the entire line but what i really need is the number.

The number is random

mklement0
  • 382,024
  • 64
  • 607
  • 775
dcaz
  • 847
  • 6
  • 15
  • 2
    Try `'Total Members in Group: (\d+)'`. The number is in the first capture group, not the entire match – Manu Oct 18 '21 at 17:00
  • 1
    How you are matching your regex? – Abdul Niyas P M Oct 18 '21 at 17:00
  • 1
    In case you're using `-match` with a single input string: If a match is found, `$Matches.1` contains what the first and only capture group (`([\d]+)`, which can be simplified to `(\d+)`) captured. – mklement0 Oct 18 '21 at 17:06
  • @AbdulNiyasPM This is where I am not sure. – dcaz Oct 18 '21 at 17:07
  • I am still not getting just the number ```$String = 'Total Members in Group: 2' $regex = '(?s)^.+\bTotal Members in Group: (\d+).*$' $String -match $regex``` This gives me ```true``` but what is the number @mklement0 – dcaz Oct 18 '21 at 17:19

2 Answers2

4
cls
$string = 'Total Members in Group: 2'
$membersCount = $string -replace "\D*"
$membersCount

One more way:

cls
$string = 'Total Members in Group: 2'
$membersCount = [Regex]::Match($string, "(?<=Group:\s*)\d+").Value
$membersCount
Fors1k
  • 490
  • 2
  • 7
1

Fors1k's helpful answer shows elegant solutions that bypass the need for a capture group ((...)) - they are the best solutions for the specific example in the question.

To answer the general question as to how to extract substrings if and when capture groups are needed, the PowerShell-idiomatic way is to:

  • Either: Use -match, the regular-expression matching operator with a single input string: if the -match operation returns $true, the automatic $Matches variable reflects what the regex captured, with property (key) 0 containing the full match, 1 the first capture group's match, and so on.

    $string = 'Total Members in Group: 2'
    if ($string -match '(?s)^.*\bTotal Members in Group: (\d+).*$') {
      # Output the first capture group's match
      $Matches.1
    }
    
    • Note:
      • -match only ever looks for one match in the input.

      • Direct use of the underlying .NET APIs is required to look for all matches, via [regex]::Matches() - see this answer for an example.

      • While -match only populates $Matches with a single input string (with an array, it acts as a filter and returns the sub-array of matching input strings), you can use a switch statement with -Regex to apply -match behavior to an array of input strings; here's a simplified example (outputs '1', '2', '3'):

        switch -Regex ('A1', 'A2', 'A3') {
          'A(.)' { $Matches.1 }
        }
        
  • Or: Use -replace, the regular-expression-based string replacement operator, to match the entire input string and replace it with a reference to what the capture group(s) of interest captured; e.g, $1 refers to the first capture group's value.

    $string = 'Total Members in Group: 2'
    $string -replace '(?s)^.*\bTotal Members in Group: (\d+).*$', '$1'
    
    • Note:
      • -replace, unlike -match, looks for all matches in the input
      • -replace also supports an array of input strings, in which case each array element is processed separately (-match does too, but in that case it does not populate $Matches; as stated, switch can remedy that).
      • A caveat re -replace is that if the regex does not match, the input string is returned as-is
mklement0
  • 382,024
  • 64
  • 607
  • 775