Re: [讨论] JSON Parse

楼主: CindyLinz (Cindy Wang)   2014-10-08 16:42:48
※ 引述《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

Links booklink

Contact Us: admin [ a t ] ucptt.com