代码之家  ›  专栏  ›  技术社区  ›  somejkuser

异常JSON解析

  •  -2
  • somejkuser  · 技术社区  · 7 年前

    {1} 或者可能 {2} 我需要解析它并获得解析的整数。

    package main
    
    import (
        "fmt"
        "encoding/json"
    )
    
    func main(){
      jsonStr:="{1}"
      jsonData:=[]byte(jsonStr)
      var v uint
      json.Unmarshal(jsonData, &v)
      data:=v
      fmt.Println(data)
    }
    

    在本例中 data 如果 jsonStr 价值是 {2}

    我查看了API文档,发现没有没有结构的字符串解析解决方案

    3 回复  |  直到 7 年前
        1
  •  1
  •   somejkuser    7 年前

    这似乎对我有用:

    import "regexp"
    
    re:=regexp.MustCompile("[0-9A-Za-z]+")
    val:=re.FindAllString(jsonStr,-1)[0]
    
        2
  •  0
  •   reticentroot    7 年前

    一些替代regex的方法因为它们是资源密集型的,并且往往比其他解决方案慢,为了简洁起见,错误被忽略。在刺激下他们不会。

    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func main() {
        str := "{1}"
        num, _ := strconv.ParseInt(string(str[1]), 10, 64)
        fmt.Println(num)
    }
    

    或者更健壮的不在乎 {} 字段。

    package main
    
    import (
        "fmt"
        "strconv"
    )
    
    func main() {
        str := "{341}"
        num, _ := strconv.ParseInt(string(str[1:len(str)-1]), 10, 64)
        fmt.Println(num)
    }
    

    显示regex比其他解决方案慢多少的小基准图像。当其他选项可用或性能不是问题/问题时,应使用它们。 enter image description here

    甚至像这样的东西也能执行正则表达式

    var n string
    for _, r := range str {
        if unicode.IsDigit(r) {
            n += string(r)
        }
    }
    

    基准代码 https://goplay.space/#PLMtSrMTN9k

        3
  •  0
  •   maerics    7 年前

    正如注释者所指出的,您的示例字符串 are not valid JSON 因为以大括号分隔的JSON文档必须是具有键值对列表的对象(例如。 {"x":1} 2 ). OPEN_BRACE, DIGIT+, CLOSE_BRACE .

    下面的示例代码检查给定字符串的第一个rune是否是一个大括号 { ,最后一个是右大括号 } strconv.ParseInt(...) :

    func main() {
      ss := []string{"{1}", "{2}", "{-123}", "{foo}", "{10", "20}", "30"}
      for _, s := range ss {
        x, err := parseBraceNumber(s)
        fmt.Printf("s=%-10qx=%-10derr=%v\n", s, x, err)
      }
      // s="{1}"     x=1         err=<nil>
      // s="{2}"     x=2         err=<nil>
      // s="{-123}"  x=-123      err=<nil>
      // s="{foo}"   x=0         err=invalid brace number "{foo}"
      // s="{10"     x=0         err=invalid brace number "{10"
      // s="20}"     x=0         err=invalid brace number "20}"
      // s="30"      x=0         err=invalid brace number "30"
    }
    
    func parseBraceNumber(s string) (int64, error) {
      if len(s) < 3 || s[0] != '{' || s[len(s)-1] != '}' {
        return 0, fmt.Errorf("invalid brace number %q", s)
      }
      x, err := strconv.ParseInt(s[1:len(s)-1], 10, 64)
      if err != nil {
        return 0, fmt.Errorf("invalid brace number %q", s)
      }
      return x, nil
    }
    

    当然,其他策略也是可能的(例如使用正则表达式),最终由您决定什么实现最适合您的用例。