1

I have a string in Powershell that is a javascript object. That is, it is a line of text stripped from a Javascript file, for instance, I might have

$theline = "{'prod_id':'123456789','prod_price':'100.00','prod_name':'Creative Software Package','prod_img':'https://mysite/images/123456789?$400x350$','prod_desc':'Software - Package - PC - Win7 - x64'};"

The Javascript elements might have values which contain more than just alphanumeric characters, and I don't think I can guarantee that they won't contain commas.

What I need to do is convert this variable into a Powershell Hash table.

First I was thinking about converting the string into a syntax that would match the ConvertFrom-StringData cmdlet. So the end result would be something like...

$convertedstr = @'
prod_id = 123456789
prod_price = 100.00
prod_name = Creative Software Package
prod_img = https://mysite/images/123456789?$400x350$
prod_desc = Software - Package - PC - Win7 - x64
'@
$table = ConvertFrom-StringData $convertedstr
$table

Name                           Value
----                           -----
prod_desc                      Software - Package - PC - Win7 - x64
prod_name                      Creative Software Package
prod_id                        123456789
prod_img                       https://mysite/images/123456789?$400x350$
prod_price                     100.00

But I'm not sure how to go about the string replace to get that done. I also found the ConvertFrom-JSON cmdlet, but since I'm on Powershell 2.0 it isn't available to me.

I had tried something like

$theline = $theline -Replace "\{'(\w+)':'(.+)',?\};",'$1 = $2`n'

But it isn't matching it the way I'd like.

$theline

prod_name = Creative Software Package','prod_id':'123456789','prod_price':'100.00`n

I get why the regex is matching what it is, but I'm not sure how to get it to match each "element."

Any ideas for this? I'm open to something that might be easier than this string conversion and a regex replace as well.

Thanks in advance.

2
  • Why are you restricted to PowerShell v2? Commented Jul 14, 2014 at 21:20
  • Making a script in a corporate environment. Upgrading would required a System Deployment, which I don't have access to request. Basically there is a bunch of red tape I'd have to go through to upgrade the Powershell version to the point where'd it take several weeks before the version is upgraded, and even then I have no guarantee it would get approved. Commented Jul 14, 2014 at 21:26

1 Answer 1

2

Trim the { from the start, and the }; from the end, and that basically leaves you with an array of Key:Value pairs. Then just create a PSCustomObject, and add members to it for each pair by splitting that array on the , and doing a RegEx match on each one.

$theline = "{'prod_id':'123456789','prod_price':'100.00','prod_name':'Creative Software Package','prod_img':'https://mysite/images/123456789?$400x350$','prod_desc':'Software - Package - PC - Win7 - x64'};"
$JavaImport = New-Object PSObject
$theline.TrimStart("{").trimend("};").split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{Add-Member -InputObject $JavaImport -NotePropertyName ($Matches[1]) -NotePropertyValue ($Matches[2])}
PS C:\Users\TMTech> $JavaImport

prod_id    : 123456789
prod_price : 100.00
prod_name  : Creative Software Package
prod_img   : https://mysite/images/123456789?$
prod_desc  : Software - Package - PC - Win7 - x64

And I just realized you wanted a hashtable. My bad. Let my revise that a hair.

$theline = "{'prod_id':'123456789','prod_price':'100.00','prod_name':'Creative Software Package','prod_img':'https://mysite/images/123456789?$400x350$','prod_desc':'Software - Package - PC - Win7 - x64'};"
$JavaImport = @{}
$theline.TrimStart("{").trimend("};").split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{$JavaImport.add($Matches[1],$Matches[2])}
PS C:\Users\TMTech> $JavaImport

Name                           Value                                                                
----                           -----                                                                
prod_desc                      Software - Package - PC - Win7 - x64                                 
prod_img                       https://mysite/images/123456789?$                                    
prod_id                        123456789                                                            
prod_price                     100.00                                                               
prod_name                      Creative Software Package 

This is already accepted, but I thought I'd comment on the origin line there. Because the OP was inputting it with double quotes we actually lost part of the URL. I ended up changing it to the following on my end:

$theline = '''prod_id'':''123456789'',''prod_price'':''100.00'',''prod_name'':''Creative Software Package'',''prod_img'':''https://mysite/images/123456789?$400x350$'',''prod_desc'':''Software - Package - PC - Win7 - x64'''

That way I could better match his desired input text. After that I stopped losing the $400x350 on the URL. Also, the RegEx escaping is a good idea, so the final solution for the user was:

$theline = '''prod_id'':''123456789'',''prod_price'':''100.00'',''prod_name'':''Creative Software Package'',''prod_img'':''https://mysite/images/123456789?$400x350$'',''prod_desc'':''Software - Package - PC - Win7 - x64'''
$JavaImport = @{}
[regex]::escape($theline).split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{$JavaImport.add([regex]::unescape($Matches[1]),[regex]::unescape($Matches[2]))}
Sign up to request clarification or add additional context in comments.

4 Comments

Awesome! Worked like a charm. I modified it a tad, since I actually have control over how the javascript string is originally built, so I don't need the trim function. Also it looked like maybe I needed to escape some regex characters? Either way, here is what I changed it to. $theline = [regex]::escape($theline) $JavaImport = @{} $theline.split(",")|?{$_ -match "^'(.+?)':'(.+?)'$"}|%{$JavaImport.add([regex]::unescape($Matches[1]),[regex]::unescape($Matches[2]))}
Also I forgot about the ungreedy modifier (.+?). Thanks, that is what was also messing things up.
Just saw your edit. Actually the original Javascript string $theline={...}; is getting pulled from a text file, and piped into the Select-String cmdlet to match a regex pattern. So I don't think I'd need to worry about the double-quote vs. single-quote issue. $theline = Get-Content .\file.txt | Select-String -pattern "MYPATTERN"
That was more so for anybody trying to replicate things. I assumed you were pulling from a file. These answers (hopefully) get used by future users with similar issues rather than just posting the same question over and over again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.