簡體   English   中英

正則表達式匹配嵌套的 json 對象

[英]Regex to match nested json objects

我正在實現某種解析器,我需要定位和反序列化嵌入到其他半結構化數據中的json 對象。 我使用了正則表達式:

\\{\\s*title.*?\\}

定位對象

{title:'Title'}

但它不適用於嵌套對象,因為表達式只匹配第一個找到的右大括號。 為了

{title:'Title',{data:'Data'}}

它匹配

{title:'Title',{data:'Data'}

所以字符串對於反序列化無效。 我知道考慮到貪婪的業務,但我不熟悉正則表達式。 你能幫我擴展表達式以使用所有可用的右大括號嗎?

更新:

需要明確的是,這是一種嘗試從 HTML+JS 等帶有嵌入 JSON 的半結構化數據中提取 JSON 數據的嘗試。 我正在使用 GSon JAVA lib 來實際解析提取的 JSON。

正如其他人所建議的那樣,一個成熟的 JSON 解析器可能是要走的路。 如果要匹配上面簡單示例中的鍵值對,可以使用:

(?<=\{)\s*[^{]*?(?=[\},])

對於輸入字符串

{title:'Title',  {data:'Data', {foo: 'Bar'}}}

這匹配:

 1. title:'Title'
 2. data:'Data'
 3. foo: 'Bar'

這個遞歸 Perl/PCRE 正則表達式應該能夠匹配任何有效的 JSON 或 JSON5 對象,包括嵌套對象和邊緣情況,例如 JSON 字符串或 JSON5 注釋中的大括號:

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

當然,這有點難讀,所以你可能更喜歡評論版本:

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

感謝@Sanjay T. Sharma 指出我“大括號匹配”,因為我最終對貪婪的表達有了一些了解,也感謝其他人最初說我不應該做什么。 幸運的是,結果證明可以使用表達式的貪婪變體

\\{\s*title.*\\}

因為右括號之間沒有非 JSON 數據。

這絕對太可怕了,我不敢相信我真的把我的名字放在了這個解決方案中,但是你能不能找到 Javascript 塊中的第一個{字符並嘗試通過適當的 JSON 解析庫解析剩余的字符? 如果它有效,你就有一個匹配。 如果沒有,請繼續閱讀直到下一個{字符並重新開始。

那里有一些問題,但它們可能可以解決:

  • 您需要能夠識別 Javascript 塊。 大多數語言都有 HTML 到 DOM 庫(我是Cyber​​neko for Java 的忠實粉絲),這使得專注於<script>...</script>塊變得容易。
  • 您的 JSON 解析庫需要在發現錯誤后立即停止使用流中的字符,並且在發生錯誤時不需要關閉流。

一個改進是,一旦你找到第一個{ ,尋找匹配的}一個(一個簡單的計數器,當你找到一個{時遞增,當你找到一個}時遞減}應該可以解決問題。 嘗試將結果字符串解析為 JSON。 迭代直到它工作或者你用完了可能的塊。

這是丑陋的,駭人聽聞的,永遠不應將其用於生產代碼。 不過,我的印象是您只需要在批處理作業中使用它,這就是我什至建議它的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM