顯示廣告
隱藏 ✕
※ 本文為 dinos 轉寄自 ptt.cc 更新時間: 2014-10-08 20:13:03
看板 RegExp
作者 CindyLinz (Cindy Wang)
標題 Re: [討論] JSON Parse
時間 Wed Oct  8 16:42:48 2014


※ 引述《b60413 (None)》之銘言:
: 我有一筆很大的json資料(萬筆以上)需要parse,
: 可是實際上每次在存取時,
: 都只是需要其中的10幾筆資料,
: 一次將資料轉換成JSON物件又會吃掉很多記憶體,
: 所以想要用正規式做字串分析,
: 但寫出來的正規式實在又臭又長,
: 因此想跟板友討教是否有更簡便的寫法,
: 最大的問題在於每筆資料的第18欄可能是陣列,
: 導致無法使用\[.*?\]來切割,
: 資料內容大約如下:
: {
:     "0000001":[1,2,0,0,0,0,0,0,0,0,0,0,1,1,"0.0","0.0",3,0,0,0,0,0,7],
:     "0000002":[2,2,0,0,0,0,0,0,0,0,0,0,1,1,"0.0","0.0",3,0,1,0,0,0,7],
:     "0000003":[3,2,0,0,0,0,0,0,0,0,0,0,1,1,"0.0","0.0",3,0,[1,1,1],0,0,0,7]
: }
: 目前使用的正規式如下:
: \"(0000002|0000003)\":\[((.+?),+){18}(?(?=\d+).+?|\[.+?\]).*?\]
「正規的」正規表示式應該沒辦法處理 JSON 這種有遞迴結構的東西..

不過如果是 perl 這種有擴充的正規表示式倒是可以, 我試寫了兩個版本,
 第一個是比較短, 但很難讀的版本:
    if( $line =~ /
        "(0000002|0000003)":\[
          ((
            \[(|(?-2)(,(?-3))*)\]|
            \{(|(?-4):(?-4)(,(?-5):(?-5))*)\}|
            "(\\.|[^"])*"|
            '(\\.|[^'])*'|
            [^,]+
          ),){18}
          ((?-8))
          (,(?-9))*
        \]/x ) {
        print "Y $10\n";
    } else {
        print "N\n";
    }

 第二個是比較長, 但比較好讀的版本:
    if( $line =~ /
        (?(DEFINE)
         (?<ITEM> \s*( (?&ARRAY) | (?&OBJECT) | (?&STRING) | (?&OTHER) )\s* )
         (?<ARRAY> \[( | (?&ITEM) (, (?&ITEM))* )\] )
         (?<OBJECT> \{( | (?&ITEM) : (?&ITEM) (, (?&ITEM) : (?&ITEM) )* )\} )
         (?<STRING> " (\\.|[^"])* " | ' (\\.|[^'])* ' )
         (?<OTHER> [^,]* )
        )
        "(0000002|0000003)": \[ ((?&ITEM),){18} (?<CATCH> (?&ITEM)) (,(?&ITEM))* \]
    /x ) {
        print "Y $+{CATCH}\n";
    } else {
        print "N\n";
    }

發現原 po 需要的好像不用完整的 JSON.. XD
 不過都寫那麼多了留著好惹.. XD

--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 112.121.80.249
※ 文章網址: http://www.ptt.cc/bbs/RegExp/M.1412757770.A.452.html
※ 編輯: CindyLinz (112.121.80.249), 10/08/2014 16:55:07

--
※ 看板: dinos 文章推薦值: 0 目前人氣: 0 累積人氣: 212 
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇