In PowerShell, there are four separate sources of commands you can pick from when trying to solve a problem. In this mini-series, we look at all of them. The problem to solve is always the same: how to capitalize the first letter in a word. Note that this is an arbitrary problem we just picked as an example. The solution strategies apply to any problem you may want to solve with PowerShell.
If you can’t find a specialized cmdlet or .NET method that can solve your problem (and we did find these in the previous parts), one last resort can be “regex” (regular expressions). This string pattern and manipulation technique is from the 70s but fully supported in PowerShell.
Identifying the first character in a word is relatively simple using regex and the -match operator, then looking into the match result found in $matches:
PS> " theword" -match '\b\w' True PS> $matches[0] t
Essentially, the regex has searched for the first word character (\w) following a word boundary (\b). Responding to such change and actually capitalizing characters though is nothing regex can do easily.
PowerShell though can use the .NET type [Regex] to call PowerShell code whenever a match was found.
Here’s a solution that capitalizes each first letter in a word:
$text = "thIS is A TEST teXT" [Regex]::Replace($text.ToLower(), '\b\w', { # this is the match that was selected by regex # in this case, it is the FIRST word character (\w) # following a word boundary (\b), so it is always # the first character of any word: param($OldValue) # do whatever you want to do with the selected character # in this case, make it always upper case: $OldValue.Value.ToUpper()})
Note that the regex example is capitalizing word beginnings only. It will not also “normalize” duplicate spaces like the .NET API method did.
If you want to normalize spaces as well, for regex that’s another task, yet a trivial one. Ask regex to replace two or more spaces with one, like this:
PS> "Here are more spaces than needed" -replace '\s{2,}', ' ' Here are more spaces than needed
You can add this to the function or apply to any text anywhere. With this same technique you can also turn fixed-width table data into CSV, for example like this:
PS> qprocess USERNAME SESSIONNAME ID PID IMAGE >tobia console 1 10952 sihost.exe >tobia console 1 10988 svchost.exe ... PS> (qprocess).SubString(1) -replace '\s{2,}', ',' | ConvertFrom-CSV USERNAME : tobia SESSIONNAME : console ID : 1 PID : 10952 IMAGE : sihost.exe USERNAME : tobia SESSIONNAME : console ID : 1 PID : 10988 IMAGE : svchost.exe ...