Convert-String for PowerShell is like FlashFill for Excel

16251434544_ac3c18c295_m

One of the many great additions that come with Powershell v5 is the Convert-String cmdlet (there is no official documentation at this point). Convert-String along with ConvertFrom-String expose FlashExtract functionality to the PowerShell world. While ConvertFrom-String allows for some very sophisticated template based parsing (Here, here and here are some good links to get started) does Convert-String work much more like the FlashFill feature added in MS Excel.
Convert-String can parse strings based on 1 or multiple examples. Let’s look at two simple use cases:
ConvertString
Code:

'Jeffrey Snover', 'Ed Wilson', 'Bruce Payette', 'Lee Holmes' | 
   Convert-String -Example 'First Last=>_ F. Last'

1..10 | 
   foreach { [math]::Round((get-random -Minimum 1e9 -Maximum 9e9)) } | 
   Convert-String -Example '0123456789=(012) 345-6789'

In addition to the input string the cmdlet only takes an argument on the ‘Example’ parameter. The ‘Example’ parameter expects one of the following argument forms (thank you dotPeek):

Description Syntax Example
A string of the form ORIGINAL=TRANSFORMED ‘ORIGINAL=TRANSFORMED’ ‘First Last=F. L’
An array of strings of the form ORIGINAL=TRANSFORMED ‘ORIGINAL1=TRANSFORMED1’, ‘ORIGINAL2=TRANSFORMED2’ (‘Jeffery Snover=J S’, ‘Lee Holmes=L H’)
A hashtable with BEFORE and AFTER keys @{BEFORE=ORIGINAL;AFTER=TRANSFORMED’} @{
BEFORE=’First Last’;
AFTER=’F Last’}
An array of hashtables with BEFORE and AFTER key pairs @{BEFORE=ORIGINAL;AFTER=TRANSFORMED’} @{
BEFORE=’Jeffery Snover’;
AFTER=’J S’},
@{
BEFORE=’Lee Holmes’;
AFTER=’L H’}

One more thing to note about the Example parameter syntax is, that ‘\’ can be used to escape characters (e.g. if you have ‘=’ in your pattern you have to use ‘\=’ instead).
The FlashExtract engine basically automatically figures out what you want based on examples. Attempting to parse more complex patterns requires more examples, where the examples should reflect the different variations of the pattern within the string to parse. Let’s look at some more examples for illustration purpose:

$txt = @'
Pete,47,Canada
Jake,23,France
Carol,33,Italy
Jane,18,Ireland
'@ -split "`n"
$ex = 'Pete,47,Canada=Pete is from Canada and 47 years old'
$txt | Convert-String -Example $ex

Whoops, this didn’t work out. This time around Convert-String was not able to recognize the full pattern throughout the entire input. Therefore we will need to provide more examples:

$txt = @'
Pete,47,Canada
Jake,23,France
Carol,33,Italy
Jane,18,Ireland
'@ -split "`n" 
$ex1 = 'Pete,47,Canada=Pete is from Canada and 47 years old'
$ex2 = 'Jake,23,France=Jake is from France and 23 years old'
$txt | Convert-String -Example ($ex1, $ex2)

Two examples are indeed sufficient in this case. Convert-String is also able to figure out some variations itself. Here for example the age is either one or two characters long:

$txt = @'
Pete,47,Canada
Jake,23,France
Carol,3,Italy
Jane,8,Ireland
'@ -split "`n"
$ex1 = 'Pete,47,Canada=Pete is from Canada and 47 years old'
$ex2 = 'Jake,23,France=Jake is from France and 23 years old'
$txt | Convert-String -Example ($ex1, $ex2)

Until now you might think that all this can also be quite easily achieved using previous PowerShell parsing capabilities and you would be right. While the examples so far can also make your life easier Convert-String can also do more advanced parsing which previously could be mainly done using Regular Expressions:

$txt = @'
Pete47Canada
Jake23France
Carol3Italy
Jane8Ireland
'@ -split "`n"
$ex1 = 'Pete47Canada=Pete is from Canada and 47 years old'
$ex2 = 'Jake23France=Jake is from France and 23 years old'
$txt | Convert-String -Example ($ex1, $ex2)

Pretty cool, huh?
Even more examples:

$txt = @'
Pete12/25/1966Canada
Jake3/14/1975France
Carol4/1/2012Italy
Jane8/17/2000Ireland
'@ -split "`n"
$ex1 = 'Pete12/25/1966Canada=Pete was born in 1966 and lives in Canada'
$ex2 = 'Carol4/1/2012Italy=Carol was born in 2012 and lives in Italy'
$txt | Convert-String -Example $ex1, $ex2

$txt = @'
Pete12/25/1966Canada
Jake3/14/1975France
Carol4/1/2012Italy
Jane8/17/2000Ireland
'@ -split "`n"
$ex1 = 'Pete12/25/1966Canada=Pete 12 Canada'
$ex2 = 'Carol4/1/2012Italy=Carol 4 Italy'
$txt | Convert-String -Example $ex1, $ex2 | 
    foreach { 
        $name, $month, $country = $_.Split()
        "$name was born in $((Get-Date -Month $month).ToString('MMMM')) and lives in $country" 
    }

$txt = @'
Pete$12.77Canada
Jake$13.8France
Carol$14.989Italy
Jane$17.99Ireland
'@ -split "`n"
$txt | Convert-String -Example 'Pete$12.77Canada=12,77'

Convert-String can make all of us string parsing rock stars!

shareThoughts


Photo Credit: Eric@focus via Compfight cc

Advertisements

I'd love to hear what you think

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s