Skip to content

Instantly share code, notes, and snippets.

@jhoneill
Last active February 15, 2022 08:17
Show Gist options
  • Save jhoneill/6470361ecd3e398f354c6a60e8b07e8d to your computer and use it in GitHub Desktop.
Save jhoneill/6470361ecd3e398f354c6a60e8b07e8d to your computer and use it in GitHub Desktop.
# rev 0.2 added more comments, and made the regax a bit more precise.
function SplitEmUp {
param (
$paramString
)
#This regex will isolate quoted blocks e.g. " -example )( $quote "
# and will identify matching open and close () {} and [] even if nested.
$opensAndCloses = @'
(?x) # Allow comments and ignore spaces and line breaks in the layaout.
^(?> # Start and make the repeating group ‘atomic’.
"" # Consume "" and '' (open/close). Next, deal with quoted stuff inc escapes.
| ''
| (?<Quoted>".*?[^"`]") # Match (and stack) "xx", "x(x" or "x`"x"; end at next " unless it is "", \" or `".
| (?<Quoted>'.*?[^']') # Match (and stack) 'xx', 'x(x' & 'x''x'; end at next ' unless it is''.
| (?<!\w)(?<Param>-\w+) # Match (and stack) pwsh style -ParameterName.
| -(?!\w)|(?<=\w)- # Consume a - when it is not starting a parameter,
| [^-$(){}\[\]"']+ # and any string of non-open/close chars,
| \$(?![({\[]) # and $ when not followed by an open bracket.
| (?<Open> \$?[(\[{]) # Match open-bracket or $open-bracket & push onto the "open" stack.
| (?<Block-Open> [)\]}]) # For a close bracket, pop the last open off the stack...
(?<= # and push text from open to close onto the "Block" stack,
\( \k<Block> \) # but IT ONLY MATCHES IF , looking back shows <open> Block <matching-close>
| \[ \k<Block> \]
| \{ \k<Block> \}
)
)+$ # Repeat up to the end.
(?(Open)(?!)) # Fail if anything is left on the "open" stack. There may be things in Block, Param and Quoted.
'@
$r = [regex]$opensAndCloses
$g = $r.Matches($paramString).Groups
#we should now have a group named BLOCK. This will hold everything wrapped in {} () or []
#(a + (b +c) ) gives two blocks the whole thing and (b+c). We don't care, We just want to ignore parametrs which start inside a block
$ignore = $g.where({$_.name -eq 'Block'}).captures
#So get the parameters where the index (the - sign) isn't in a block, and add a dummy one for end of text
$params = @() + $g.where({$_.name -eq 'param'}).captures |
Where-Object {$i = $_.index; -not $ignore.where({$_.index -le $i -and ($_.index +$_.length) -ge $i})}
$params += [pscustomobject]@{index=$paramString.Length }
#We have the unbracketted parameters slice their values out of the string to be hashtable values
$i = 0
$hash = [ordered]@{}
while ($params[$i].value) { #I cheated - the end stop doesn't have a value property only index.
$pValueStart = $params[$i].index + $params[$i].Length
$pValueLength = $params[$i+1].index - $pvalueStart
$hash[$params[$i].value -replace "^-",''] = $paramString.Substring($pValueStart, $pValueLength).Trim()
$i ++
}
$hash
}
SplitEmUp '-prefix $(prefix) -nt0applicationStartPort $(ntappIicationStartPort) -nt0applicationEndPort $(ntapplicationEndPort) -_artifactsLocation $(StorageContainerUri) -_artifactsLocationSasToken (ConvertTo-SecureString ''$(StarageCantainerSAS)'' -AsPlainText -Force) -clusterName'
#Quoted
#'-prefix $(prefix) -nt0applicationStartPort $(ntappIicationStartPort) -nt0applicationEndPort $(ntapplicationEndPort) -_artifactsLocation $(StorageContainerUri) -_artifactsLocationSasToken (ConvertTo-SecureString ''$(StarageCantainerSAS)'' -AsPlainText -Force) -clusterName'
# ^-----------------------^ <=Inside quotes () don't count as a block
#Blocks
#'-prefix $(prefix) -nt0applicationStartPort $(ntappIicationStartPort) -nt0applicationEndPort $(ntapplicationEndPort) -_artifactsLocation $(StorageContainerUri) -_artifactsLocationSasToken (ConvertTo-SecureString ''$(StarageCantainerSAS)'' -AsPlainText -Force) -clusterName'
# ^-------^ ^-----------------------^ ^---------------------^ ^--------------------^ ^---------------------------------------------------------------------^
#Parameters
#'-prefix $(prefix) -nt0applicationStartPort $(ntappIicationStartPort) -nt0applicationEndPort $(ntapplicationEndPort) -_artifactsLocation $(StorageContainerUri) -_artifactsLocationSasToken (ConvertTo-SecureString ''$(StarageCantainerSAS)'' -AsPlainText -Force) -clusterName'
# ^-----^ ^----------------------^ ^--------------------^ ^-----------------^ ^-------------------------^ ^----------^ ^-----^ ^----------^
#Parameters, with blocks ignored + end stop
#'-prefix $(prefix) -nt0applicationStartPort $(ntappIicationStartPort) -nt0applicationEndPort $(ntapplicationEndPort) -_artifactsLocation $(StorageContainerUri) -_artifactsLocationSasToken (ConvertTo-SecureString ''$(StarageCantainerSAS)'' -AsPlainText -Force) -clusterName'
# ^-----^ ^----------------------^ ^--------------------^ ^-----------------^ ^-------------------------^ ^----------^^
#Splits
#'-prefix $(prefix) -nt0applicationStartPort $(ntappIicationStartPort) -nt0applicationEndPort $(ntapplicationEndPort) -_artifactsLocation $(StorageContainerUri) -_artifactsLocationSasToken (ConvertTo-SecureString ''$(StarageCantainerSAS)'' -AsPlainText -Force) -clusterName'
# prefix=| | nt0applicationStartPort=| |nt0applicationEndPort=| | _artifactsLocation=| | _artifactsLocationSasToken=| |clusterName=||'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment