Regular Expressions
Prerequisites: Operators, Reading and writing text files
PowerShell uses .NET regular expressions throughout: -match,
-replace, -split, switch -Regex, and Select-String.
-match and $Matches
$line = 'Order #1042 shipped to London on 2025-04-22'
if ($line -match '#(\d+).* to (\w+) on (\d{4}-\d{2}-\d{2})') {
"Order: $($Matches[1]), City: $($Matches[2]), Date: $($Matches[3])"
}
if ($line -match '#(?<id>\d+)') {
"Named group: $($Matches.id)"
}
Order: 1042, City: London, Date: 2025-04-22
Named group: 1042
Named groups ((?<id>...)) make patterns self-documenting.
Finding every match
-match finds only the first match. For all of them, use [regex]:
$text = 'Contact ada@example.com or linus@example.org for access.'
[regex]::Matches($text, '[\w.]+@[\w.]+\w') | ForEach-Object Value
ada@example.com
linus@example.org
-replace with groups
'2025-04-22' -replace '(\d{4})-(\d{2})-(\d{2})', '$3/$2/$1'
'John Smith' -replace '(?<first>\w+) (?<last>\w+)', '${last}, ${first}'
'too many spaces' -replace '\s+', ' '
22/04/2025
Smith, John
too many spaces
Use single quotes for the replacement, so PowerShell doesn't treat
$1 as a variable.
Select-String: grep for PowerShell
Set-Content app.log @'
INFO Server started
ERROR Database timeout after 30s
INFO Request served
ERROR Disk usage at 95%
'@
Select-String -Path app.log -Pattern 'ERROR' | ForEach-Object { "$($_.LineNumber): $($_.Line)" }
Select-String -Path app.log -Pattern '(\d+)(s|%)' | ForEach-Object { $_.Matches[0].Value }
2: ERROR Database timeout after 30s
4: ERROR Disk usage at 95%
30s
95%
Select-String returns match objects with LineNumber, Line,
Filename, and Matches. Search many files at once with
Get-ChildItem -Recurse -Filter *.log | Select-String 'ERROR'.
Build and test patterns interactively with the Regex Tester.