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.
In the previous part we already used PowerShell operators and generic string methods to solve the problem. However, there’s a common truth in code: the more specialized the commands are that you use the less complicated will the code be on your side.
That’s why there’s another source of commands that PowerShell can use: static .NET methods from one of the thousands of .NET libraries that ship with PowerShell. And here’s a solution that is so much simpler than using generic operators and string methods:
$text = "thIS is A TEST teXT" [CultureInfo]::InvariantCulture.TextInfo.ToTitleCase($text)
Words that are ALL CAPITALIZED will remain untouched:
This Is A TEST Text
If you don’t like the exception for all capitalized words, then convert your text to all lowercase before you send it to the method:
PS> [CultureInfo]::InvariantCulture.TextInfo.ToTitleCase('TEST remains aLL uppER Case') TEST Remains All Upper Case PS> [CultureInfo]::InvariantCulture.TextInfo.ToTitleCase('TEST remains aLL uppER Case unless you lowerCASE YOUR text beFORE'.ToLower()) Test Remains All Upper Case Unless You Lowercase Your Text Before
As you see here (when compared to previous parts of this series), whitespaces remain untouched as well since we never split the text into individual words. If you don’t like this and would like to “normalize” whitespace to one space exactly, simply add the -replace operator which can fine-tune any string:
$text = "thIS is A TEST teXT" # title convert and then replace two or more spaces with one space only: [CultureInfo]::InvariantCulture.TextInfo.ToTitleCase($text.ToLower()) -replace '\s{2,}', ' '
Now this approach returns the exact same result as in our previous parts:
This Is A Test Text
The code above is short and simple so you could directly use it in your code wherever appropriate, but will you remember next week or next month when you may need the same conversion again?
So again, consider wrapping the code in a function. You could update the function we created in part 2 with our new and more efficient code approach:
function Convert-CapitalizeWord { param ( [Parameter(Mandatory,ValueFromPipeline)] $Text ) process { [CultureInfo]::InvariantCulture.TextInfo.ToTitleCase($text.ToLower()) -replace '\s{2,}', ' ' } }
Once you run the function, it will be just as flexible and scalable as before:
# you get automatic prompts when you forget to submit mandatory arguments: PS> Convert-CapitalizeWord cmdlet Convert-CapitalizeWord at command pipeline position 1 Supply values for the following parameters: Text: heLLO WOrld Hello World # you can submit your text to the -Text parameter: PS> Convert-CapitalizeWord -Text 'this iS a LONG teXT' This Is A Long Text # you can pipe as many texts as you like (scalable) via the pipeline: PS> 'Hello world!', 'someTHING else' | Convert-CapitalizeWord Hello World! Something Else