regex - PostgreSQL:正则表达式用大括号替换第一级方括号

标签 regex postgresql

我在 PostgreSQL 列中有一个 TEXT 类型的数据,我需要对其进行一些字符替换。具体来说,我想用大括号替换方括号。要注意的是,如果包含主要的封闭括号,我只想替换深度不超过两层的括号。这些字符串可能很长,所以我认为正则表达式可能是可行的方法(regexp_replace 函数),但我不擅长正则表达式。这是一个这样的值的示例:

[0,0,0,[12,2],0,0,[12,[1,2,3]],12,0,[12,2,[2]],12,0,12,0,0]

所以我希望这个字符串更改为:

{0,0,0,{12,2},0,0,{12,[1,2,3]},12,0,{12,2,[2]},12,0,12,0,0}

提前致谢!

最佳答案

这将是一个痛苦的正则表达式作为 in PostgreSQL flavor possibly no recursion is available .

对于最多 2 级嵌套深度 检查,如果以下双重替换有效(无法测试)

regexp_replace(
  regexp_replace('str', E'\\[(([^][]|\\[([^][]|\\[[^][]*\\])*\\])*)\\]', E'{\\1}', 'g')
, E'\\[(([^][]|\\[([^][]|\\[[^][]*\\])*\\])*)\\]', E'{\\1}', 'g')

思路是匹配替换最外层的[]在两次传球中。 请参阅 regex101 中的示例:

pass 1 : {0,0,0,[12,2],0,0,[12,[1,2,3]],12,0,[12,2,[2]],12,0,12,0,0}
pass 2 : {0,0,0,{12,2},0,0,{12,[1,2,3]},12,0,{12,2,[2]},12,0,12,0,0}

\[[^][]*\] (未转义)匹配 [...] 的一个实例

  • \[左方括号
  • [^][]*后跟任意数量的字符,不能是方括号
  • \]后跟右方括号

请注意,如果字符串始终以 [ 开头, 以 ] 结尾并表示第 0 级的一个实例(不被 ][ 分隔)第一个/内部 regexp_replace也可以通过替换 [ 来完成在^开始和]$结束:E'^\\[(.*)\\]$'E'{\\1}'


要在此处添加最多 4 层深度的示例:

\[([^][]|    # outer
\[([^][]|    # lvl 1
\[([^][]|    # lvl 2
\[([^][]|    # lvl 3
\[[^][]*\]   # lvl 4
)*\]
)*\]
)*\]
)*\]

包裹外面的东西[]进入 capture group 4 个级别的模式将变为:

\[(([^][]|\[([^][]|\[([^][]|\[([^][]|\[[^][]*\])*\])*\])*\])*)\]

用于 regex_replace可能需要额外转义 []

\\[(([^][]|\\[([^][]|\\[([^][]|\\[([^][]|\\[[^][]*\\])*\\])*\\])*\\])*)\\]

这可以像两次传递中的第一个模式一样使用,并用 E'{\\1}' 代替

关于regex - PostgreSQL:正则表达式用大括号替换第一级方括号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26072947/

相关文章:

正则表达式:在 R 中使用 `u` 标志

c# - 处理未知数量的捕获组时仅替换一组

Postgresql,将 CSV 字符串转换为数组

postgresql - Postgres 使用 debezium 创建复制槽失败

sql - 具有字符串路径的分层数据 - 查询节点,获取所有父节点及其节点的第一级

mysql - 从 mysql 中的字符串中获取哈希标签

c - 正则表达式:C 函数的返回类型

php - 用于匹配空格或字符串结尾的正则表达式

ruby-on-rails - 无法在 Heroku 上部署基本的 Rails 应用程序

mysql - Openproject 安装到 PostGre 而不是 MySQL