PowerShell Regex: Match Email, IP Address, and URL Patterns

Writing regex from scratch for every script that validates an email or extracts an IP address is unnecessary — a small library of battle-tested patterns covers the vast majority of real-world cases. This post gives you ready-to-use PowerShell regex email IP URL pattern code for the six most common validation and extraction scenarios. Copy, test, and adapt them for your scripts without getting lost in character class notation.
Email Address Validation Pattern
A pragmatic email regex accepts the vast majority of valid addresses without rejecting unusual but legitimate ones. This pattern handles subdomains, plus signs, dots in the local part, and multi-part TLDs. It deliberately avoids the RFC-compliant patterns that are hundreds of characters long and still reject valid edge cases.
# Email validation pattern
$emailPattern = '^[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}$'
# Test it
$addresses = @('[email protected]', '[email protected]', 'bad@', '@missing.com', 'no-at-sign')
foreach ($addr in $addresses) {
$valid = $addr -match $emailPattern
Write-Host "$addr : $(if ($valid) {'Valid'} else {'Invalid'})"
}
[email protected] : Valid
[email protected] : Valid
bad@ : Invalid
@missing.com : Invalid
no-at-sign : Invalid
IPv4 Address Pattern
A simple \d{1,3} pattern matches numbers but cannot enforce the 0–255 range. The pattern below validates each octet explicitly to prevent false positives like 999.999.999.999. Use it when you need strict IP format validation, not just digit-and-dot matching.
# IPv4 with octet range validation (0-255)
$ipPattern = '^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$'
$ips = @('192.168.1.1', '10.0.0.0', '255.255.255.255', '999.1.1.1', '192.168.1')
foreach ($ip in $ips) {
Write-Host "$ip : $($ip -match $ipPattern ? 'Valid' : 'Invalid')"
}
# Extract all IPs from a log file
Select-String -Path C:\Logs\firewall.log -Pattern $ipPattern |
ForEach-Object { $_.Matches.Value } | Sort-Object -Unique
URL Extraction Pattern
This pattern extracts HTTP and HTTPS URLs from text, including those with query strings and fragments. It handles common URL characters but intentionally does not try to validate every possible URL scheme to keep the pattern practical.
# URL extraction from text
$urlPattern = 'https?://[^\s"''<>]+'
$text = 'Visit https://powershelltips.com and see https://docs.microsoft.com/en-us/powershell for docs.'
$urls = [regex]::Matches($text, $urlPattern) | ForEach-Object { $_.Value }
$urls
https://powershelltips.com
https://docs.microsoft.com/en-us/powershell
Date Pattern (Multiple Formats)
Date formats vary by locale and application. These patterns cover the most common formats you encounter in log files and data exports. Named groups make it easy to extract individual components for further processing.
# MM/DD/YYYY or DD/MM/YYYY or YYYY-MM-DD
$isoDate = '\b(\d{4})-(\d{2})-(\d{2})\b' # 2024-03-15
$usDate = '\b(\d{1,2})/(\d{1,2})/(\d{4})\b' # 3/15/2024
$euDate = '\b(\d{1,2})\.(\d{1,2})\.(\d{4})\b' # 15.03.2024
# Named groups for ISO date
$namedDate = '(?<Year>\d{4})-(?<Month>\d{2})-(?<Day>\d{2})'
$logLine = 'Transaction completed 2024-03-15 at 14:32:01'
if ($logLine -match $namedDate) {
Write-Host "Year: $($Matches.Year), Month: $($Matches.Month), Day: $($Matches.Day)"
}
Phone Number Pattern
Phone numbers have many valid formats. This pattern accepts the most common North American formats with optional country code, area code separators, and extension notation. Adjust for international formats as needed.
# North American phone number — various formats
$phonePattern = '^(\+?1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)(\d{3}[-.\s]?\d{4})(\s?(x|ext\.?)\s?\d{1,5})?$'
$phones = @(
'555-123-4567',
'(555) 123-4567',
'+1 555.123.4567',
'5551234567',
'555-123-4567 x890',
'12345'
)
foreach ($p in $phones) {
Write-Host "$p : $($p -match $phonePattern ? 'Valid' : 'Invalid')"
}
GUID and Hex String Patterns
GUIDs appear in Windows event logs, registry keys, and application IDs. Hex strings are used for hashes, certificate thumbprints, and binary data representation. Both have fixed formats that are easy to match exactly.
# GUID pattern (with or without braces)
$guidPattern = '\{?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\}?'
# 64-character hex string (SHA256 hash)
$sha256Pattern = '^[0-9a-fA-F]{64}$'
# Extract GUIDs from text
$eventText = 'Application ID: {6D809377-6AF0-444B-8957-A3773F02200E} started'
if ($eventText -match $guidPattern) {
Write-Host "Found GUID: $($Matches[0])"
}
# Validate a SHA256 hash
$hash = '3A7BD3E2360A3D29EEA436FCFB7E44719FE7BCF6E8D5A0BFED6A3B6E3C3D4F1'
Write-Host "Valid SHA256: $($hash -match $sha256Pattern)"
Common Errors and Fixes
- Overly strict email regex rejects valid addresses. RFC 5321 allows many unusual characters in email local parts, including quotes and parentheses. Any pattern that tries to cover every RFC case becomes unmaintainable. Use a pragmatic pattern that passes all common addresses and handle edge cases at a higher level (e.g., send a verification email).
- IPv4 pattern must also validate 0-255 range not just digits.
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}matches999.999.999.999. Use the full octet-range pattern shown above to correctly reject invalid addresses like256.1.1.1.
Related Cmdlets / See Also
Wrapping Up
These six patterns cover emails, IPs, URLs, dates, phone numbers, and GUIDs — the patterns you encounter in log parsing, data validation, and API integration every week. Keep them in a snippets library, test each one against your specific data format before deploying, and use named groups whenever you need to extract specific components from a match.


