I have a PowerShell script that scans a line of text for a given regex pattern, corresponding to a Date and/or Time, and extracts the Date/Time string for further processing.
Example:
#List of user inputs
$dateformat = 'M/d/yyyy,HH:mm:ss.fff'
$regexFormat = '\d{1,2}\/\d{1,2}\/\d{4}\,\d{1,2}\:\d{1,2}\:\d{1,2}\.\d{3}'`
The script then searches for that regex pattern in a line of input text, e.g.
$input = '6/5/2025,08:37:38.058,1.0527,-39.5013,38.072,1.0527,-39.5013'
The script works well, but currently requires the user to build the regex pattern manually. I am targeting this tool for users who don't need to have PowerShell or coding experience.
My goal is to add a function to methodically build up a regex pattern given only an example format user input such as
$formatinput1 = 'M/d/yyyy,HH:mm:ss.fff'
$formatinput2 = 'yyyy-MM-dd,HH:mm:ss'
$formatinput3 = 'yyyy-MM-dd hh:mm:ss [A|P]M'
or else a sample string user input
$sampleinput1 = '6/5/2025,08:37:38.058'
$sampleinput2 = '2025-06-05,08:37:38'
$sampleinput3 = '2025-6-5 8:37:38 AM'
The user would give the example string as an input, and the function would build up a corresponding regex pattern to use in the text search.
My current thought is to simply create a look-up table of regex formats for all of the most common date formats (and update it when I come across a new one).
But I am wondering if there is a more methodical way?
Here is a pretty simple regex pattern generator. My approach is really simple, just parsing the end user suitable input string like yyyy-MM-dd,HH:mm:ss
or 2025-06-05,08:37:38
and building a new regex pattern by exchanging all chars or digits by \d
or escaping some chars like .
, /
or \
.
The main issue was to correctly handle the specific [A|P]M
pattern, but I think it should be OK. Honestly, it is not super perfect, but fine for getting a clue how it could be done.
Please let me know if you need further explanations about my code and I will add it here tomorrow.
function new-regex-pattern {
param (
[string]$s
)
$ampm = '[A|P]M'
if (($s -match [Regex]::Escape($ampm)) -or ($s -match $ampm)) {
$regexOptions = [Text.RegularExpressions.RegexOptions]'IgnoreCase, CultureInvariant'
if ($s -match [Regex]::Escape($ampm)) {
$pattern = -join ('(?<start>.*)(?<AM_PM>',
[Regex]::Escape($ampm), ')(?<end>.*)')
}
else {
$pattern = -join ('(?<start>.*)(?<AM_PM>', $ampm, ')(?<end>.*)')
}
$regexPattern = [Regex]::new($pattern, $regexOptions)
$match = $regexPattern.Matches($s)
return (convert-pattern $match[0].Groups['start'].Value) +
$match[0].Groups['AM_PM'].Value +
(convert-pattern $match[0].Groups['end'].Value)
}
return convert-pattern $s
}
function convert-pattern {
param (
[string]$s
)
if ($s.Length -gt 0) {
foreach ($c in [char[]]$s) {
switch ($c) {
{ $_ -match '[A-Z0-9]' } { $result += '\d' }
{ $_ -match '\s' } { $result += '\s' }
{ $_ -eq '.' } { $result += '\.' }
{ $_ -eq '/' } { $result += '\/' }
{ $_ -eq '\' } { $result += '\\' }
default { $result += $_ }
}
}
}
return $result
}
$formatinput1 = 'M/d/yyyy,HH:mm:ss.fff'
$formatinput2 = 'yyyy-MM-dd,HH:mm:ss'
$formatinput3 = 'yyyy-M-d h:mm:ss [A|P]M'
$sampleinput1 = '6/5/2025,08:37:38.058'
$sampleinput2 = '2025-06-05,08:37:38'
$sampleinput3 = '2025-6-5 8:37:38 AM'
$example1 = '6/5/2025,08:37:38.058,1.0527,-39.5013,38.072,1.0527,-39.5013'
$example2 = '2025-06-05,08:37:38,1.0527,-39.5013,38.072,1.0527,-39.5013'
$example3 = '2025-6-5 8:37:38 AM,1.0527,-39.5013,38.072,1.0527,-39.5013'
$regexPattern = [Regex]::new((new-regex-pattern $formatinput1))
Write-Host $regexPattern.Matches($example1)
$regexPattern = [Regex]::new((new-regex-pattern $formatinput2))
Write-Host $regexPattern.Matches($example2)
$regexPattern = [Regex]::new((new-regex-pattern $formatinput3))
Write-Host $regexPattern.Matches($example3)
$regexPattern = [Regex]::new((new-regex-pattern $sampleinput1))
Write-Host $regexPattern.Matches($example1)
$regexPattern = [Regex]::new((new-regex-pattern $sampleinput2))
Write-Host $regexPattern.Matches($example2)
$regexPattern = [Regex]::new((new-regex-pattern $sampleinput3))
Write-Host $regexPattern.Matches($example3)