PowerShell Regex: How to Use Regular Expressions (With Examples)

PowerShell regex (regular expressions) lets you match, extract, replace and split text by pattern. The operators -match, -replace and -split all take a regex, and $Matches holds what -match found:

$text = 'Order ORD-5812 ships to Austin, TX'

$text -match 'ORD-(\d+)'
"Whole match: $($Matches[0])"
"Order number: $($Matches[1])"

Output:

True
Whole match: ORD-5812
Order number: 5812
PowerShell regex -match operator and the $Matches variable
-match returns True, and $Matches holds the whole match and the captured group (PowerShell 7)

Below I cover case sensitivity, named groups, replacing, splitting, finding every match, Select-String and switch -Regex. Every example ran in PowerShell 7.6 and 5.1, and all the data is made up.

Regex basics in PowerShell

PowerShell uses the .NET regex engine. A few tokens cover most everyday patterns:

TokenMatchesExample
\dOne digit\d{4} matches 2026
\wLetter, digit or underscore\w+ matches Austin
\sWhitespace\s+ matches spaces and tabs
.Any character except a newlinea.c matches abc
^ and $Start and end of the string^ORD matches at the start
( )Capture groupORD-(\d+) captures 5812
[ ]Any one character in the set[;,] matches ; or ,

Microsoft’s regular expression quick reference lists every token.

The -match operator is the quickest way to try a pattern, as shown in the -match operator.

-match is case-insensitive, -cmatch isn’t

Like most PowerShell operators, -match ignores case. Use -cmatch when case matters:

'INVOICE inv-20431' -match 'INV-\d+'
'INVOICE inv-20431' -cmatch 'INV-\d+'

Output:

True
False

The same rule applies to -replace and -creplace, and -split and -csplit. The -match operator in depth covers matching against arrays.

Capture data with named groups

Named groups, written (?<Name>…), make a pattern easier to read and the results easier to use. Here I break a log line into parts:

$line = '2026-09-14 08:16:44 ERROR [Billing] Card declined for order ORD-5812'
$pattern = '^(?<Date>\S+) (?<Time>\S+) (?<Level>\w+)\s+\[(?<Area>\w+)\] (?<Message>.+)$'

if ($line -match $pattern) {
    "Level:   $($Matches.Level)"
    "Area:    $($Matches.Area)"
    "Message: $($Matches.Message)"
}

Output:

Level:   ERROR
Area:    Billing
Message: Card declined for order ORD-5812
PowerShell regex named capture groups parse a log line
Named groups pull the level, area and message out of one log line (Windows PowerShell 5.1)

Each group name becomes a key in $Matches. Extracting text between delimiters shows more capture patterns.

Replace text with -replace

-replace takes a pattern and a replacement, and $1, $2 refer to your groups. This reformats phone numbers written three different ways:

$phones = '512-555-0147', '214.555.0199', '713 555 0123'
$phones -replace '^(\d{3})[-. ](\d{3})[-. ](\d{4})$', '($1) $2-$3'

Output:

(512) 555-0147
(214) 555-0199
(713) 555-0123
PowerShell regex -replace with capture groups reformats phone numbers
Three phone number formats become one with a single -replace (PowerShell 7)

Put the replacement in single quotes. In double quotes, PowerShell would treat $1 as a variable before the regex sees it. Replacing text in strings covers plain-text replacements too.

Split on a pattern with -split