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

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:
| Token | Matches | Example |
|---|---|---|
| \d | One digit | \d{4} matches 2026 |
| \w | Letter, digit or underscore | \w+ matches Austin |
| \s | Whitespace | \s+ matches spaces and tabs |
| . | Any character except a newline | a.c matches abc |
| ^ and $ | Start and end of the string | ^ORD matches at the start |
| ( ) | Capture group | ORD-(\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

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

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.