Ruby 修复/使用带前导零(0';s)的无效JSON数字?e、 g.“;03“;

Ruby 修复/使用带前导零(0';s)的无效JSON数字?e、 g.“;03“;,ruby,regex,json,parsing,nokogiri,Ruby,Regex,Json,Parsing,Nokogiri,我有一个JSON字符串,我可以从网站上抓取它。我只需要以下数据(原始字符串要长得多),这里是检索到的JSON,我计划将其转换为Ruby哈希: {"day": 15, "month": 03, "year": 2012, "hour": 10, "min": 00, "sec": 00} 我使用正则表达式检索了上述json: targetDate:\s+(.*?)}\)/m 我无法解析上面的json,因为整数中有额外的零。(00和03) 我试着用3代替03,用0代替00手动改变数字,结果成功了

我有一个JSON字符串,我可以从网站上抓取它。我只需要以下数据(原始字符串要长得多),这里是检索到的JSON,我计划将其转换为Ruby哈希:

{"day": 15, "month": 03, "year": 2012, "hour": 10, "min": 00, "sec": 00}
我使用正则表达式检索了上述json:

targetDate:\s+(.*?)}\)/m
我无法解析上面的json,因为整数中有额外的零。(00和03) 我试着用3代替03,用0代替00手动改变数字,结果成功了

所以,我猜json解析器可能无法查看这种数字

问题是,如何清理上面检索到的JSON,以便删除不必要的零。就是

{"day": 15, "month": 3, "year": 2012, "hour": 10, "min": 0, "sec": 0}
谢谢你的帮助

json.gsub(/(?<=[: ])0+(\d+,)/, "\\1")
看起来更好,但也有可能“智胜”这个regexp。 Regexp不太适合此类问题

好的,以下是非regexp解决方案:

var inString = false; # check, whether current char is in string. Think of it as whether current symbol would be highlighted as string constant in editor
var out = []; # array/stack for output
var prevChar = null; # previous char. One may init to space symbol or even replace it with `out[-1]` everywhere
for (chr in jsonStr) { # iterate over symbols (chars) of a string
    if (char == '"' && prevChar != "\\") inString = !inString;
    if (!isDigit(out[-2])
    &&  prevChar == '0'
    &&  isDigit(chr)) { # i.e. last 3 chars match /(\D)0(\d)/
        out[-1] = prevChar = chr; # make it \1\2
    } else {
        out.push(prevChar = chr); # just continue building string
    }
}
out.join("");
将其视为类似javascript的伪代码,但未经测试。

试试这个regexp

json = '{"day": 15, "month": 03, "year": 2012, "hour": 10, "min": 00, "sec": 00}'
json.gsub(/\b0*(\d+)/, '\1')
#=> {"day": 15, "month": 3, "year": 2012, "hour": 10, "min": 0, "sec": 0}
编辑:


虽然不是严格必需的(请参见注释),
\b
字边界确保只能匹配数字开头的零。

与其引入正则表达式,不如对其进行求值:

hash = eval '{"day": 15, "month": 03, "year": 2012, "hour": 10, "min": 00, "sec": 00}'.gsub(': ', ' => ')

这是我试图解析它时的错误消息:710:unexpected-token在{“day”:15,“month”:03,“year”:2012,“hour”:10,“min”:00,“sec”:00}您是正确的。我忘记了JSON禁止数字(0.xyz除外)以零开头。次要更正:JSON禁止除
0
本身和
0.xyz
以外的任何数字以零开头。将
“年”:2012
更改为
“年”:212
,并从所有数字中删除除最后一个零以外的所有数字numbers@kirilloid当前位置我也这么认为,但事实上它不这样做。当匹配
2012
时,
0*
部分查看
2
并失败,因此
\d+
匹配
2012
,一切正常。但是我想通过在开头添加一个
\b
单词边界来明确它,因为这有点违反直觉。谢谢。它确实起作用了`test=JSON.parse('{“日”:15,“月”:03,“年”:2012,“时”:10,“分”:00,“秒”:00}).gsub(/0*(\d+/,'\1'))#=>test['year']给出2012@TimPietzcker,我想你是对的。我会尽量使我的版本更直观,并张贴在这里。谢谢@TimPietzcker嗯,这真的很好用。我仍然可以提供一个糟糕的例子:
{“电话号码”:“123-05-07”}
嘿!又是你!经过测试,你的答案确实有效。更简单更干净!谢谢不客气。如果里面可能有恶意代码,不要这样做。没关系。我只是为了练习才用这个。但正如我所读到的,他们说使用eval通常不是一个好主意。我发现,这段代码在像
“\\”
hash = eval '{"day": 15, "month": 03, "year": 2012, "hour": 10, "min": 00, "sec": 00}'.gsub(': ', ' => ')