Regexp with PowerShell, more than a match

<img alt="" src="/images/4/3/c/f/a/43cfa60210120dfeb0b71fd0d29d1d8ee310b9ff-match.png" />

Regexp with PowerShell, more than a match

18, Jul Klaas

In this article I show where regular expressions can appear in PowerShell. You probably know you can use a regexp in -match, but there are some other interesting uses.

Case

I did use some simple regular expressions now and then, but was recently confronted with a situation where it seemed the only option to solve a problem for a new dbatools function, and I wouldn't get there with my basic knowledge.
As first refuge, I turned to Bruce and Richard; Windows Powershell in Action, Third Edition and as expected, they had something to say about the subject. :-) Coincidentally, I was pointed to Reuven M. Lerner's free regexp crash course by e-mail the next day, and decided to subscribe.
So I learned both regexp syntax and rules, and the PowerShell implementation of it.
In the E-book, Ctrl+F kept spewing next results, so much that I decided to start with an overview of the uses of regexp in PowerShell before diving deeper into each case.

I will not explain the regexp syntax here.
Also, it's important to realise we don't need regexp as much as on UNIX command shell. But there are cases where regexp comes to the rescue, like when searching through text files, or handling the output of external commands, e.g. netstat, nslookup,...

Pattern matching operators

-match

When matching an input string to a pattern, we have two well-known operators in PowerShell: -like and -match. With -like we can only use wildcards and compose very simple patterns. In fact, behind the scenes those patterns are translated to regexp as well. But if we want something more complex, we have to turn to -match, where we have the complete regexp gamma to our disposal.

We're talking not only -match, but also all of these variations:

  • -match
  • -imatch
  • -cmatch
  • -notmatch
  • -inotmatch
  • -cnotmatch

where i stands for 'case insensitive' and c for 'case sensitive'.

You probably know the operators return $true or $false. But they also populate the $matches variable, and that is very handy! Look at this random and totally useless example:

"This is just a sentence" -match '\s(\w(\w(\w)))'

match

-split

Again, there are some variations:

  • -split
  • -isplit
  • -csplit
"This is just a sentence" -split '\s'

split

-replace

With -replace, or actually:

  • -replace
  • -ireplace
  • -creplace

we can substitute matches with literals:

"This is just a sentence" -replace '\s','...'

replace

regex type

The [regex] type accelerator creates a .NET regular expression object System.Text.RegularExpressions.Regex.

regextype

match() method

This type of object has a .match() method:

regextypematch

split() method

... and also a .split() method:

regextypesplit

Select-String -pattern

This is like grep if you ever encountered that. The Select-String cmdlet finds a -pattern in text.
It has an -allmatches switch to ... guess what :-)

Get-ChildItem D:\Myscripts -File -Recurse *.sql | Select-String -pattern "drop\s+[?(database|table|login)"

will get us all our sql scripts in which we drop a database, table or login.
The returned MatchInfo object holds the matching parts of the script text, and also the name of the file and the line number where the match was found.

param ValidatePattern

When defining parameters we can write a list of valid values in [ValidateSet], or set limits with [ValidateRange], but when we use [ValidatePattern] we can demonstrate our regexp magic.

Param(
    [ValidatePattern('^\d{3}[/.-]?\d{6}$')]
    [string]$customercode
    )

Downside is the error message that is quite hard to understand. So sometimes it's more convenient to use [ValidateScript] where we can match to a regex as well, and write our own error messages.

switch statement -regex

In the switch statement we have a -regex parameter that we use when we want to write regex to match the inputobject to a condition. If the inputobject is not a string, this parameter is ignored.

switch

This easy conditional counter shows I have more sql scripts than PowerShell scripts.

Resources

I'll come back at this very interesting topic in other articles. For now, if you'd like to learn more on yourself, see these sources of wisdom:

Get-Help about_Regular_Expressions

Microsoft Docs on Regular Expressions
Reuven M Lerner
Unicode Org
Windows Powershell in Action, Third Edition
Regular-Expressions.info

To be continued

Hopefully this overview makes you feel a bit more familiar with the place of regexp in PowerShell. Of course there is a lot more to tell, and I will write some additional articles on some of the uses mentioned above.

Previous Post Next Post