0

我所拥有的和我所知道的:

  • json 数组,例如 {"home":["1","2","5"], "work":["15","16","19"]}
  • 新的整数元素(例如“11”)
  • 新元素“家”或“工作”的位置(例如“家”)

我需要的:

  • 将此元素添加到 json 数组末尾的正确位置
  • 用正则表达式来做
  • 使用 regexp_replace 在 postgreSQL 中执行此操作
  • 结果必须是这样的: {"home":["1","2","5","11"], "work":["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');

我不知道的是: - 如果地方是“家”:[],我必须把“11”不带“,”!如何?

4

2 回答 2

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,但 regex 也肯定不是一个好的工具。PL/v8绝对是 JSON 处理的合法选择。

于 2015-02-14T00:19:05.043 回答
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}$

你可以在这里看到一个例子。

注意:你可以在没有显式量词的情况下做同样的事情:

("home":\[)(?:(].*)("[^"]*"$)|([^]]+)(.*)(,"[^"]*"$))|,"[^"]*"$
于 2015-02-13T23:18:01.800 回答