Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Archives
Log in
June 5, 2026

Regex Capturing with PowerShell

In this issue:

  • [Regex]
    • Invoking Regex Methods
    • Regex Options
    • Leveraging Methods
  • Summary

A few weeks ago I wrote a few newsletters on regular expression fundamentals. This isn't specifically a PowerShell topic, but it is something that you will find very helpful in your scripting projects. And PowerShell makes it very easy to use. You just have to learn the syntax for the regex task at hand. Today, I want to cover a few advanced topics.

[Regex]

As I showed last time, you can define a regular expression pattern as a string when using a regular expression operator like -match.

PS C:\> dir c:\work\ -file | where name -match "\.ps[dm]1$"

    Directory: C:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           7/18/2025 11:35 AM           7686 m.psd1
-a---           3/11/2026  3:24 PM           2886 PSWorkItem.psd1
-a---           3/11/2026  3:26 PM           7193 PSWorkItem.psm1

Can you decipher the pattern? I am looking for files where the name ends in a literal period, the letters ps followed by either d or m and then 1.

Another way to define a regular expression pattern is to use the [regex] type accelerator. Assuming you don't need any advanced regular expression features which most people rarely need, you can create a regex object like this:

PS C:\> [regex]$rx = "\.ps[dm]1$"
PS C:\> $rx

Options RightToLeft MatchTimeout
------- ----------- ------------
   None       False -00:00:00.0010000

PS C:\> $rx.GetType().FullName
System.Text.RegularExpressions.Regex

This object has many methods you will want to take advantage of.

PS C:\> $rx | Get-Member -MemberType Method | Select Name,Definition

Name                Definition
----                ----------
Count               int Count(string input), int Count(System.ReadOnlySpan[char…
EnumerateMatches    System.Text.RegularExpressions.Regex+ValueMatchEnumerator E…
EnumerateSplits     System.Text.RegularExpressions.Regex+ValueSplitEnumerator E…
Equals              bool Equals(System.Object obj)
GetGroupNames       string[] GetGroupNames()
GetGroupNumbers     int[] GetGroupNumbers()
GetHashCode         int GetHashCode()
GetObjectData       void ISerializable.GetObjectData(System.Runtime.Serializati…
GetType             type GetType()
GroupNameFromNumber string GroupNameFromNumber(int i)
GroupNumberFromName int GroupNumberFromName(string name)
IsMatch             bool IsMatch(string input), bool IsMatch(string input, int …
Match               System.Text.RegularExpressions.Match Match(string input), S…
Matches             System.Text.RegularExpressions.MatchCollection Matches(stri…
Replace             string Replace(string input, string replacement), string Re…
Split               string[] Split(string input), string[] Split(string input, …
ToString            string ToString()

Let me re-write my first example.

PS C:\> dir c:\work -file | where {$rx.IsMatch($_.Name)}

    Directory: C:\work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           7/18/2025 11:35 AM           7686 m.psd1
-a---           3/11/2026  3:24 PM           2886 PSWorkItem.psd1
-a---           3/11/2026  3:26 PM           7193 PSWorkItem.psm1

The IsMatch() method returns a boolean value.

This makes it easy to filter file names, although I wish there were a way to filter with regular expressions using Get-ChildItem. One thing you might do, especially if the folder has thousands of files is to filter where you can with Get-ChildItem and then apply a more granular filter with Where-Object.

dir c:\work -file -filter *.ps* | where {$rx.IsMatch($_.Name)}

The number of files I'm processing is small, but this did improve performance by 50%.

You can also use the regex object to get match information.

PS C:\> $rx.Match("c:\foo\bar\demo.psm1")

Groups    : {0}
Success   : True
Name      : 0
Captures  : {0}
Index     : 15
Length    : 5
Value     : .psm1
ValueSpan :

Invoking Regex Methods

Where this really gets useful is when you want to use a regex method like splitting or replacing. There's nothing wrong with using the native operator.

PS C:\> "PowerShell" -split "[aeiou]"
P
w
rSh
ll
Want to read the full issue?
Already a paid subscriber? Click here to log in.
GitHub
Bluesky
LinkedIn
Mastodon
jdhitsolutions.github.io
Powered by Buttondown, the easiest way to start and grow your newsletter.