2

I'm trying to match 3 characters after in a string using PowerShell. Example:

$servername1 = "z002p002dcs001"
$serverName2 = "z002p003dcs001"
$servername3 = "z002p004dcs001"

I am only interested in the 3 digits after p, so 002, 003, 004. I know regex is required here but I'm stuck.

$serverName1 -match "p002*"
True

Good

$serverName1 -match "p003*"
True

Bad

What am I doing wrong? Why does "p003*" return a match for $serverName1?

user9924807
  • 707
  • 5
  • 22

4 Answers4

3

Your issue is with the asterix (*) character at the end. Simply removing it will fix your problem. e.g.

$serverName1 -match "p002"
True
$serverName1 -match "p003"
False

The reason why your second example returned True is because the asterix (*) character is regex for "0 or more". So what you are matching is:

p   - Matches "p"
0   - Matches "0"
0   - Matches "0"
3   - Matches "3"
 *  - Quantifier, matches 0 or more of the preceding token. e.g. "3"

This means that anything with "p00" will match.

Edit:

Going beyond, if you are interested in the 3 digits after the "p" you can use a capture group and a character set:

"p([0-9]{3})"

p       - Matches "p"
 (      - Start of Capture group
  [0-9] - Character set. Match digits 0-9
   {3}  - Quantifier, matches 3 of the preceding token e.g. any digit 0-9
 )      - End Capture group

Also, in PowerShell, you can then use the special $Matches variable to extract the number:

$regex = "p([0-9]{3})"

$servername1 = "z002p002dcs001"
$serverName2 = "z002p003dcs001"
$servername3 = "z002p004dcs001"

$serverName1 -match $regex
$Matches[1]
002

$serverName2 -match $regex
$Matches[1]
003

$serverName3 -match $regex
$Matches[1]
004
HAL9256
  • 12,384
  • 1
  • 34
  • 46
2

The ' * ' character means match anything preceding it 0 or more times. The ' * ' here would be inappropriate.

I am not exactly sure what you want to match, but p[0-9]{3} might be a better pattern.

One could execute $Matches to see what was matched previously to get an idea of what's happening.

Reference: https://www.rexegg.com/regex-quickstart.html https://regexr.com/

Shashank Holla
  • 377
  • 3
  • 12
2

To complement Hal's helpful answer, given that in the question's title you say you want to retrieve 3 characters (digits):

PS> 'z002p002dcs001',
    'z002p003dcs001',
    'z002p004dcs001' -replace '.+p(\d{3}).+', '$1'
002
003
004

This uses PowerShell's -replace operator via a regex that matches the input in full and replaces it with the 3 digits (\d{3}) that follow the (last) p character; in other words: it extracts the 3 digits that follow the (last) p.

mklement0
  • 382,024
  • 64
  • 607
  • 775
1

Asterisk in regex means 0 or more instances of previous character. Here, 3 is before asterisk and has 0 instances so it matches. "+" matches 1 or more instances of previous character. So correct regex is "p003.+".

Wasif
  • 14,755
  • 3
  • 14
  • 34