当前位置: 首页 > 面试题库 >

检查字符串是否为JSON格式

阎修明
2023-03-14
问题内容

如何检查给定的字符串是否采用以空格/换行符分隔的多个json字符串形式?

例如,
给定的:("test" 123 {"Name": "mike"}3个json与空格连接)
return :,true因为item("test" 123{"Name": "mike"})中的每个都是有效的json。

在Go中,我可以编写一个O(N ^ 2)函数,例如:

// check given string is json or multiple json concatenated with space/newline
func validateJSON(str string) error {
    // only one json string
    if isJSON(str) {
        return nil
    }
    // multiple json string concatenate with spaces
    str = strings.TrimSpace(str)
    arr := []rune(str)
    start := 0
    end := 0
    for start < len(str) {
        for end < len(str) && !unicode.IsSpace(arr[end]) {
            end++
        }
        substr := str[start:end]
        if isJSON(substr) {
            for end < len(str) && unicode.IsSpace(arr[end]) {
                end++
            }
            start = end
        } else {
            if end == len(str) {
                return errors.New("error when parsing input: " + substr)
            }
            for end < len(str) && unicode.IsSpace(arr[end]) {
                end++
            }
        }
    }
    return nil
}

func isJSON(str string) bool {
    var js json.RawMessage
    return json.Unmarshal([]byte(str), &js) == nil
}

但这不适用于大量输入。


问题答案:

有两种选择。从编码的角度来看,最简单的方法就是正常解码JSON字符串。您可以通过解码为空结构来提高效率:

package main

import "encoding/json"

func main() {
    input := []byte(`{"a":"b", "c": 123}`)
    var x struct{}
    if err := json.Unmarshal(input, &x); err != nil {
        panic(err)
    }

    input = []byte(`{"a":"b", "c": 123}xxx`) // This one fails
    if err := json.Unmarshal(input, &x); err != nil {
        panic(err)
    }
}

(游乐场链接)

此方法有一些潜在的缺点:

  • 它仅适用于单个JSONhtml" target="_blank">对象。也就是说,没有附加逻辑的情况下,对象列表(按问题的要求)将失败。
  • 正如@icza在评论中指出的那样,它仅适用于JSON对象,因此裸露的数组,数字或字符串将失败。为了适应这些类型,interface{}必须使用它,这可能会导致严重的性能损失。
  • 该扔掉的x值仍必须进行分配,以及至少一个反射调用是有可能的纸张,其可能引入显着的性能损失一些工作负载下。

鉴于这些限制,我的建议是使用第二个选项:遍历整个JSON输入,而忽略实际内容。使用标准库json.Decoder可简化此操作:

package main

import (
    "bytes"
    "encoding/json"
    "io"
)

func main() {
        input := []byte(`{"a":"b", "c": 123}`)
        dec := json.NewDecoder(bytes.NewReader(input))
        for {
            _, err := dec.Token()
            if err == io.EOF {
                break // End of input, valid JSON
            }
            if err != nil {
                panic(err) // Invalid input
            }
        }

        input = []byte(`{"a":"b", "c": 123}xxx`) // This input fails
        dec = json.NewDecoder(bytes.NewReader(input))
        for {
            _, err := dec.Token()
            if err == io.EOF {
                break // End of input, valid JSON
            }
            if err != nil {
                panic(err) // Invalid input
            }
        }
}

(游乐场链接)



 类似资料:
  • 问题内容: 我想创建一个函数来接收输入字符串,该字符串可以是json格式的字符串,也可以只是一个字符串。例如,以下功能很简单。 问题答案: 我不清楚您是否仅需要了解“引号字符串”,还是需要了解json或两者之间的区别,因此,这向您展示了如何检测这两种情况,因此您可以非常具体。 我也在这里发布了交互式代码示例:http : //play.golang.org/p/VmT0BVBJZ7 将输出以下内容

  • 问题内容: 我有一个isNotEmpty函数,如果字符串不为空,则返回true;如果字符串为空,则返回false。我发现如果我通过它传递一个空字符串,它将无法正常工作。 使用isNotEmpty验证字符串: 如果该字符串为空,则其他字符串将不会执行,我不明白为什么,请有人对此有所帮助。 问题答案: 实际上是简单的问题。更改: 至 可以说,您可能还想将其更改为: 因为如果您传递的是数字0以及其他一些

  • 问题内容: JavaScript中是否可以检查字符串是否为URL? 正则表达式被排除在外,因为URL的写法很像;也就是说,它可能没有,或者。 问题答案: 与答案相关的问题: 或来自Devshed的此正则表达式:

  • 我用Json创建了一个数据库。我解析了这个数据库,并让代码遍历一个包含几个Json对象的Json数组。最后,我也在遍历Json对象中的值。我的问题是我需要检查迭代器所在的值是字符串还是数组。 谷歌似乎只有检查字符串中是否有数字或该问题的其他变体之类的事情。 所以,这些问题似乎对我想要的东西没有多大帮助。有一个案例与我的非常相似,但它处理的是原始数据类型,所以我处理字符串的案例不起作用。(这里是另一

  • null 我会避免使用moment.js这样的库

  • 问题内容: 假设我有一个包含一些字母和标点符号的String数组 在字母[3]中,我们带有“。” 如何检查字符串是否为标点符号?我们知道有许多可能的标点符号(,。?!等) 到目前为止,我的进度: 问题答案: 您是否还需要检查更多标点符号? 如果是这样,您可以执行此操作。