0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ConvertFrom-Json for PowerShell v2

Posted at

必要になったので書きました。1

Crockford 先生(?)のパーサ を PowerShell で書き直しただけです。reviver と一部のエラーチェックはサボっています。

Function ConvertFrom-Json {
    param(
        [Parameter(ValueFromPipeline=$True)]
        [string[]]$InputObject
    )
    begin {
        $buf = New-Object System.Text.StringBuilder
    }
    process {
        foreach($b in $InputObject){
            $buf.Append($b) > $null
        }
    }
    end {
        $ErrorActionPreference = "Stop"
        $script:json = $buf.ToString()
        $script:at = 0
        $script:ch = " "
        $script:escape = New-Object psobject |
            Add-Member -PassThru NoteProperty '"' '"' |
            Add-Member -PassThru NoteProperty "\" "\" |
            Add-Member -PassThru NoteProperty "/" "/" |
            Add-Member -PassThru NoteProperty "b" "`b" |
            Add-Member -PassThru NoteProperty "f" "`f" |
            Add-Member -PassThru NoteProperty "n" "`n" |
            Add-Member -PassThru NoteProperty "r" "`r" |
            Add-Member -PassThru NoteProperty "t" "`t"
        $script:err = {
            param($m)
            throw "Syntax Error: $m, $at, $json"
        }
        $script:next = {
            param($c)
            if ($c -and $c -ne $ch) { & $err "Expected '$c' instead of '$ch'" }
            $script:ch = $json[$at]
            $script:at += 1
        }
        $script:number = {
            $str = ""
            $e = ""
            if ($ch -eq "-") {
                $str = "-"
                & $next "-"
            }
            while($ch -ge "0" -and $ch -le "9") {
                $str += $ch
                & $next
            }
            if ($ch -eq "."){
                $str += "."
                & $next
                while($ch -ge "0" -and $ch -le "9") {
                    $str += $ch
                    & $next
                }
            }
            if ($ch -eq "e") {
                & $next "e" # skip e
                if ($ch -eq "+" -or $ch -eq "-") {
                    $e += $ch
                    & $next
                }
                while($ch -ge "0" -and $ch -le "9") {
                    $e += $ch
                    & $next
                }
            }
            $number = [double]$str
            if ($e) { $number *= [Math]::Pow(10, [int]$e) }
            if ($number) {
                return $number
            } else {
                & $err "Bad Number"
            }
        }
        $script:string = {
            $str = ""
            if ($ch -eq '"') {
                & $next
                while($ch){
                    if($ch -eq '"') {
                        & $next
                        return $str
                    } elseif ($ch -eq "\") {
                        & $next
                        if ($ch -eq "u") {
                            $uffff = 0
                            1..4 | ForEach-Object {
                                & $next
                                $hex = [Convert]::ToInt32($ch, 16)
                                $uffff = $uffff * 16 + $hex
                            }
                            $str += [char]::ConvertFromUtf32($uffff)
                        } elseif ($escape.$ch){
                            $str += $escape.$ch
                        } else {
                            break
                        }
                    } else {
                        $str += $ch
                    }
                    & $next
                }
            }
            & $err "Bad String"
        }
        $script:white = {
            while($ch -and $ch -le " ") {
                & $next
            }
        }
        $script:word = {
            switch($ch){
                "t" {
                    & $next "t"
                    & $next "r"
                    & $next "u"
                    & $next "e"
                    return $true
                }
                "f" {
                    & $next "f"
                    & $next "a"
                    & $next "l"
                    & $next "s"
                    & $next "e"
                    return $false
                }
                "n" {
                    & $next "n"
                    & $next "u"
                    & $next "l"
                    & $next "l"
                    return $null
                }
                default {
                    & $err "Unexpected '$ch'"
                }
            }
        }
        $script:array = {
            $arr = @()
            if ($ch -eq "[") {
                & $next "["
                & $white
                if ($ch -eq "]"){
                    & $next "]"
                    return $arr
                }
                while($ch) {
                    $arr += & $value
                    & $white
                    if ($ch -eq "]") {
                        & $next "]"
                        return $arr
                    }
                    & $next ","
                    & $white
                }
            }
            & $err "Bad Array"
        }
        $script:object = {
            $obj = New-Object PSObject
            if ($ch -eq "{"){
                & $next "{"
                & $white
                if ($ch -eq "}") {
                    & $next "}"
                    return $obj
                }
                while($ch){
                    $key = & $string
                    & $white
                    & $next ":"
                    $obj | Add-Member NoteProperty $key (& $value) # error if duplicate key
                    & $white
                    if ($ch -eq "}") {
                        & $next "}"
                        return $obj
                    }
                    & $next ","
                    & $white
                }
            }
            & $err "Bad Object"
        }
        $script:value = {
            & $white
            switch($ch){
                "{" { return & $object }
                "[" { return & $array }
                '"' { return & $string }
                "-" { return & $number }
                default {
                    if ($ch -ge "0" -and $ch -le "9") {
                        return & $number
                    } else {
                        return & $word
                    }
                }
            }
        }
        $result = & $value
        & $white
        if ($ch) {
            & $err "Syntax Error"
        }
        return $result
    }
}
  1. Windows7 と Windows Server 2008 早く消え去って欲しい

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?