正则表达式匹配嵌套的 json 对象

Vik*_*bin 9 java regex

我正在实现某种解析器,我需要定位和反序列化嵌入到其他半结构化数据中的json 对象。我使用了正则表达式:

\\{\\s*title.*?\\}
Run Code Online (Sandbox Code Playgroud)

定位对象

{title:'Title'}
Run Code Online (Sandbox Code Playgroud)

但它不适用于嵌套对象,因为表达式只匹配第一个找到的右大括号。为了

{title:'Title',{data:'Data'}}
Run Code Online (Sandbox Code Playgroud)

它匹配

{title:'Title',{data:'Data'}
Run Code Online (Sandbox Code Playgroud)

所以字符串对于反序列化无效。我知道考虑到贪婪的业务,但我不熟悉正则表达式。你能帮我扩展表达式以使用所有可用的右大括号吗?

更新:

需要明确的是,这是一种尝试从 HTML+JS 等带有嵌入 JSON 的半结构化数据中提取 JSON 数据的尝试。我正在使用 GSon JAVA lib 来实际解析提取的 JSON。

dav*_*son 6

正如其他人所建议的那样,一个成熟的 JSON 解析器可能是要走的路。如果要匹配上面简单示例中的键值对,可以使用:

(?<=\{)\s*[^{]*?(?=[\},])
Run Code Online (Sandbox Code Playgroud)

对于输入字符串

{title:'Title',  {data:'Data', {foo: 'Bar'}}}
Run Code Online (Sandbox Code Playgroud)

这匹配:

 1. title:'Title'
 2. data:'Data'
 3. foo: 'Bar'
Run Code Online (Sandbox Code Playgroud)


Dev*_*ine 6

这个递归 Perl/PCRE 正则表达式应该能够匹配任何有效的 JSON 或 JSON5 对象,包括嵌套对象和边缘情况,例如 JSON 字符串或 JSON5 注释中的大括号:

/(\{(?:(?>[^{}"'\/]+)|(?>"(?:(?>[^\\"]+)|\\.)*")|(?>'(?:(?>[^\\']+)|\\.)*')|(?>\/\/.*\n)|(?>\/\*.*?\*\/)|(?-1))*\})/
Run Code Online (Sandbox Code Playgroud)

当然,这有点难读,所以你可能更喜欢评论版本:

m{
  (                               # Begin capture group (matching a JSON object).
    \{                              # Match opening brace for JSON object.
    (?:                             # Begin non-capturing group to contain alternations.
      (?>[^{}"'\/]+)                  # Match a non-empty string which contains no braces, quotes or slashes, without backtracking.
    |                               # Alternation; next alternative follows.
      (?>"(?:(?>[^\\"]+)|\\.)*")      # Match a double-quoted JSON string, without backtracking.
    |                               # Alternation; next alternative follows.
      (?>'(?:(?>[^\\']+)|\\.)*')      # Match a single-quoted JSON5 string, without backtracking.
    |                               # Alternation; next alternative follows.
      (?>\/\/.*\n)                    # Match a single-line JSON5 comment, without backtracking.
    |                               # Alternation; next alternative follows.
      (?>\/\*.*?\*\/)                 # Match a multi-line JSON5 comment, without backtracking.
    |                               # Alternation; next alternative follows.
      (?-1)                           # Recurse to most recent capture group, to match a nested JSON object.
    )*                              # End of non-capturing group; match zero or more repetitions of this group.
    \}                              # Match closing brace for JSON object.
  )                               # End of capture group (matching a JSON object).
}x
Run Code Online (Sandbox Code Playgroud)

  • 当然是认真的回答了!这个正则表达式*完全*满足了问题的要求:定位并提取嵌入在非 JSON 数据中的 JSON 对象,正确处理嵌套对象和边缘情况。然后可以将匹配与 JSON 解析器一起使用来反序列化 JSON 对象。 (2认同)

Vik*_*bin 3

感谢@Sanjay T. Sharma 指出我“大括号匹配”,因为我最终对贪婪表达式有了一些了解,也感谢其他人最初说我不应该做什么。幸运的是,事实证明使用贪婪的表达式变体是可以的

\\{\s*title.*\\}
Run Code Online (Sandbox Code Playgroud)

因为右括号之间没有非 JSON 数据。