如何在Postgres中添加新的json元素的正则表达式

时间:2015-02-13 22:29:12

标签: regex json postgresql-9.3 regexp-replace

我拥有的和我所知道的:

  • json array喜欢{" home":[" 1"," 2"," 5"],"工作& #34;:[" 15"" 16"" 19"]}
  • 新的整数元素(" 11"例如)
  • 新元素的地方" home"或者"工作" ("家庭"例如)

我需要什么:

  • 将此元素添加到正确位置的json数组的末尾
  • 使用reqular表达式
  • 使用regexp_replace
  • 在postgreSQL中执行此操作
  • 结果必须如下:{" home":[" 1"," 2"," 5",&#34 ; 11"],"工作":[" 15"," 16"," 19"]}

我尝试了什么:

SELECT regexp_replace('{"home":["1","2","5"], "work":["15","16","19"]}', '(.*)("home":\[)(("[0-9]*",)*("[0-9]*")*)(\])(.*)', '\1\2\3,"11"\6\7', 'g');

我不知道的事: - 如果地方将是" home":[]我必须把" 11"没有","!如何?

2 个答案:

答案 0 :(得分:1)

我不是postgresql专家,但你可以试试这个技巧:

SELECT regexp_replace('{"home":["1","2","5"], "work":["15","16","19"]}' || ',"11"', '("home":\[)(?:(].*)(.{4}$)|([^]]+)(.*)(.{5}$))|.{5}$', '\1\3\4\2\6\5', 'g');

之前的想法是将原始字符串与,"11"连接起来。当数组为空时,组3仅捕获"11",但当数组不为空时,组6捕获,"11"

.{5}$将匹配字符串末尾的,"11",并且由于所有捕获组都为空,因此替换字符串将删除它。

显然,量词必须适应您想要添加的字符串的长度。因此,如果您想添加13240,则模式将为:

("home":\[)(?:(].*)(.{7}$)|([^]]+)(.*)(.{8}$))|.{8}$

您可以看到示例here

注意:如果没有明确的量词,你可以这样做:

("home":\[)(?:(].*)("[^"]*"$)|([^]]+)(.*)(,"[^"]*"$))|,"[^"]*"$

答案 1 :(得分:1)

不要使用正则表达式来处理JSON。这只是一个坏主意。就像HTML一样,JSON不是常规语言。应该解析JSON 进行处理。

我在纯SQL中工作了很长一段时间,而且很难看。然后我安装了PL/v8,花了我大约10分钟。安装(安装因平台而异),然后运行:

CREATE EXTENSION plv8;

然后很容易。我刚刚创建了一个函数:

CREATE OR REPLACE FUNCTION add_to_keyed_list(obj JSON, obj_key TEXT, new_value JSON)
  RETURNS JSON
  LANGUAGE plv8
  AS $$
    obj[obj_key].push(new_value);
    return JSON.stringify(obj);
  $$
;

是的,这是数据库中的JavaScript代码。

查询:

SELECT add_to_keyed_list('{"home":["1","2","5"], "work":["15","16","19"]}'::JSON, 'home', to_json('11'::TEXT));

准确地找到了你想要的东西:

{"home":["1","2","5","11"],"work":["15","16","19"]}

我认为说PG现在还没有很好的修改JSON的工具是公平的,但正则表达式当然也不是一个好的工具。 PL / v8 绝对是JSON处理的合法选择。