The support of regular expressions is a must-have feature for every modern scripting language. PowerShell offers various language constructs that allow you to work with RegEx.

Unlike in Word, Microsoft based PowerShell's RegEx implementation mostly on Perl. Thus, if you have experience with regular expressions, your learning curve in PowerShell will be relatively flat.

Compared to wildcards, regular expressions are much more powerful because they are not just limited to substrings and simple placeholders. For example, you can define ranges (like [a-d]), distinguish between character classes (numeric, alphabetic, whitespace, etc.), or match against the number of occurrences by using various quantifiers. This cheat sheet (PDF) provides a good overview of the RegEx features in PowerShell.

Pattern matching with the -Match operator

PowerShell offers a variety of comparison operators that you can not only apply to numeric values but also to string objects. One of them is -Match, which not only supports literal expressions but also RegEx:

"The regular expression in PowerShell 4.0" -Match "shell\s*(\d)"

This statement results in TRUE. This is something of a surprise because RegEx is usually case sensitive. In the above example, “PowerShell” contains the capital letter “S” whereas the regular expression uses a lower case “s.”

If you need a case sensitive comparison, you can use the -Cmatch operator. In addition, PowerShell supports the -Imatch parameter that works just like -Match. However, as its names implies, it is case insensitive, which helps avoid unwanted side effects.

With complex regular expressions, you often want to know not only whether a pattern matches or not but also to which expression it applies. The $Matches array serves this purpose. The Matches[0] variable contains the entire string that matches the pattern, and the subsequent members of the array store the so-called group matches. These are the subexpressions in parentheses (in the above example (\d)):

The $Matches array

A peculiarity of -match and its variants is that it only determines the first match; they disregards additional matches.

Select -String with the parameters -Pattern and -AllMatches

If you want to determine all matches, then the Select-String cmdlet is suitable. It supports the parameter -pattern to which you can pass a regular expression.

Although Select-String also stops after the first match, you can turn off this behavior with the -AllMatches switch:

Help about_regular_expressions | Select-String -Pattern "quanti.*" -AllMatches

Displaying all lines that match the pattern

If you only want to display the matches, you can iterate over the matches property of the returned MatchInfo object (with % as an alias for the Foreach-Object as in the following example) and then iterate again over the resulting object to extract the Value property.

Help about_reg | Select-String -Pattern "quanti.*" -AllMatches | %{$_.matches} | %{$_.Value}

Displaying all matches

Search and replace with -Replace

If you don’t just want to find text patterns but also replace them with strings, you can use the -Replace operator. As expected, it requires two arguments, the regular expression and the replacement string that you have to separate with a comma:

“Introduction to PowerShell 4.0” -Replace "\d\.", "5."

Using the -replace parameter

In contrast to -Match, the -Replace operator does not return a Boolean value that informs you whether the regular expression matches or not. Instead, it will produce the new string.

Often, you will want to replace a pattern not just with a constant string but with portions of the original string. In those cases, you usually have to capture the text matched inside groups and reuse it in the backreference variables $1, $2, $3, and so on. PowerShell automatically assigns special variables, such as $& (an entire string that matches the pattern).

The following example demonstrates how you can replace the third octet with the value “99” in all IP addresses of the hosts file that start with “192.168.”

$IPs = Get-Content -Path C:\Windows\system32\drivers\etc\hosts
$IPs -Replace "192\.168\.\d{1,3}\.(\d{1,3})", '192.168.99.$1'

Because the subpattern of the last octet is the only one that is grouped (it is in parentheses), you can capture it in the backreference variable $1 and reuse it in the new IP address.

Note that the replacement text should be in single quotation marks because PowerShell expands variables in double quotations marks before they are passed to the RegEx engine. As backreference variables are usually not preset, PowerShell will replace the variables in such a case with the empty string.

By the way, unlike the -Match operator, -Replace doesn’t store the matches in the $Match variable.

Split strings with -Split

As its name suggests, the -Split parameter splits strings at defined delimiters into multiple substrings. Typical delimiters are tabs, semicolons, and spaces.

It is more flexible to define the positions where you want to split the string with regular expressions. Check out the example below:

"Chapter 1: Introduction to PowerShell 4.0" -Split "(\d+|\s)"

Split string with RegEx

This command splits the string at every number and whitespace character.

  1. Avatar
    Steven P 7 years ago

    Hi, the RegEx cheatsheet you refer to has moved to:

    Thanks for the very useful article!


Leave a reply

Please enclose code in pre tags: <pre></pre>

Your email address will not be published. Required fields are marked *


© 4sysops 2006 - 2023


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account