omegastripes / VBA-JSON-parser

Backus-Naur Form JSON Parser based on RegEx for VBA
GNU General Public License v3.0
107 stars 44 forks source link

Parsing escaped \ #5

Closed Raph-xyz closed 4 years ago

Raph-xyz commented 5 years ago

Hello, I have an issue where an escaped anti slash is still interpreted as a special character

my input:

sValue = "[{""$id"":""1"",""$type"":""InputFile, Project_Data"",""InputFileID"":40164,""Name"":""BE5642378-900"",""FilePath"":""\\\\res.company.corp\\DCE\\av\\ateri\\BE5642378-900.CATPart"",""Main"":""ateri""}]"

the attribute FilePath should become \\res.company.corp\DCE\av... but instead the \r is replace by a line return

I don't think it's an adequate solution, but all I could find was to change in the Sub Retrieve, the Case "s" with this code

    vTransfer = Replace(Mid(sTokenValue, 2, Len(sTokenValue) - 2), "\\", "_Escaped_Anti_Slash_") 'Added this line
    vTransfer = Replace(Replace(Replace(Replace(Replace(Replace(Replace( _
                    vTransfer, _
                    "\""", """"), _
                    "\/", "/"), _
                    "\b", Chr(8)), _
                    "\f", Chr(12)), _
                    "\n", vbLf), _
                    "\r", vbCr), _
                    "\t", vbTab) 'removed a replace here:  "\\", "\"), _
    vTransfer = Replace(vTransfer, "_Escaped_Anti_Slash_", "\") 'Added this line

I think a regex would be better, but couldn't find how to implement it

omegastripes commented 4 years ago

@Raph-xyz Actually the solution you suggested is thoroughly acceptable. Going that way first I replace \\ with \ + vbNullChar (vbNullChar isn't used normally in text, that is why no collisions are possible), and after all replacements completed, change them finally back from \ + vbNullChar to \. So the fix is as follows:

            Case "s"
                vTransfer = Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace( _
                    Mid(sTokenValue, 2, Len(sTokenValue) - 2), _
                    "\""", """"), _
                    "\\", "\" & vbNullChar), _
                    "\/", "/"), _
                    "\b", Chr(8)), _
                    "\f", Chr(12)), _
                    "\n", vbLf), _
                    "\r", vbCr), _
                    "\t", vbTab)
                .Global = False
                .pattern = "\\u[0-9a-fA-F]{4}"
                Do While .test(vTransfer)
                    vTransfer = .Replace(vTransfer, ChrW(("&H" & Right(.Execute(vTransfer)(0).value, 4)) * 1))
                Loop
                vTransfer = Replace(vTransfer, "\" & vbNullChar, "\")