Postgresql: 基于分隔符替换 JSON 内的整个字符串

huangapple go评论61阅读模式
英文:

Postgresql: replacing whole strings inside json, based on delimiters

问题

I understand your request. Here's the translated content:

有没有一种在PostgreSQL中进行字符串替换的好方法,可以考虑以下情况:

  • 要替换的字符串类似于https://my.oldserver.com/api/v1/images/929009-ee-cda-6-4227-83-e-4-80-fc-954730-b-6.jpeg?id=MQkvMjAyMi8wMS8xOC85MjkwMDllZS1jZGE2LTQyMjctODNlNC04MGZjOTU0NzMwYjYuanBlZwk4OTY=
  • 我希望基于它以https://my.oldserver.com/api/v1/images/929009-ee-cda-6-4227-83-e-4-80-fc-954730-b-6.jpeg开头,它有一个?id=参数/分隔符和/或?id=<BASE64>,并以"或后面的,结束来选择和替换整个字符串
  • 最终,我希望得到一个值,类似于:https://my.newserver.com/2022/01/18/929009ee-cda6-4227-83e4-80fc954730b6.jpeg,替换第一点中的值
  • 我使用类似于以下简化示例的replace指令:
update document_revisions dr
set data = replace(
    (dr.data)::text,
    ''"url": "https://my.oldserver.com/api/v1/images',
    ''"url": "https://my.newserver.com'
  )::jsonb;

像这个示例一样直接替换一个值为另一个值似乎很简单,但根据我上面显示的一组条件选择整个字符串并不那么容易。

我将data列中的整个JSON视为文本,并尝试在这样的结构中进行替换(以及其他结构):

        {
            "identifier": "p:814:794.image",
            "id": "doc-1f73vuahm0",
            "content": {
                "img": {
                    "originalUrl": "https://my.oldserver.com/api/v1/images/covid-19-m-rna-vaccines.png?id=MQkvMjAyMS82LzEvZWI2YzQwZjItMjYzMS00MTY4LWFhZGQtNjZjMmVkOTg5ZDQ2LnBuZwk4MTQ=",
                    "url": "https://my.oldserver.com/api/v1/images/covid-19-m-rna-vaccines.png?id=MQkvMjAyMS82LzEvZWI2YzQwZjItMjYzMS00MTY4LWFhZGQtNjZjMmVkOTg5ZDQ2LnBuZwk4MTQ%3D&auto=format",
                    "mediaId": "3nO-shKnBV18",
                    "width": 1390,
                    "height": 341,
                    "mimeType": "image/png"
                },
                "caption": "COVID-19 mRNA vaccines",
                "source": "Source: Example1"
            }
        },

如何正确替换这些条目?最终,由于我有多个类似的条目,我考虑将该值存储在变量中,并逐个遍历所有需要进行的替换,但我迄今为止无法选择整个字符串,只能直接替换其中的部分。

谢谢。

英文:

Is there a good way to do a string replace in postgresql that takes this into account?:

  • The strings to replace are similar to https://my.oldserver.com/api/v1/images/929009-ee-cda-6-4227-83-e-4-80-fc-954730-b-6.jpeg?id=MQkvMjAyMi8wMS8xOC85MjkwMDllZS1jZGE2LTQyMjctODNlNC04MGZjOTU0NzMwYjYuanBlZwk4OTY=
  • I want to select and replace the whole string based on the fact that it starts with https://my.oldserver.com/api/v1/images/929009-ee-cda-6-4227-83-e-4-80-fc-954730-b-6.jpeg , it has a ?id= param/separator and/or ?id=<BASE64> and ends with a " or the following ,
  • In the end, I should end up with a value like: https://my.newserver.com/2022/01/18/929009ee-cda6-4227-83e4-80fc954730b6.jpeg, replacing the value from the first point
  • I'm using a replace instruction like this simplified example:
update document_revisions dr
set data = replace(
    (dr.data)::text,
    '"url": "https://my.oldserver.com/api/v1/images',
    '"url": "https://my.newserver.com'
  )::jsonb;

Seems pretty simple to replace a value by another directly like this example, but selecting a whole string based on the set of conditions I showed above is not so trivial?

I'm treating the whole json in the data column as text and doing attempting the replacement on structures (among others) like this:

        {
            "identifier": "p:814:794.image",
            "id": "doc-1f73vuahm0",
            "content": {
                "img": {
                    "originalUrl": "https://my.oldserver.com/api/v1/images/covid-19-m-rna-vaccines.png?id=MQkvMjAyMS82LzEvZWI2YzQwZjItMjYzMS00MTY4LWFhZGQtNjZjMmVkOTg5ZDQ2LnBuZwk4MTQ=",
                    "url": "https://my.oldserver.com/api/v1/images/covid-19-m-rna-vaccines.png?id=MQkvMjAyMS82LzEvZWI2YzQwZjItMjYzMS00MTY4LWFhZGQtNjZjMmVkOTg5ZDQ2LnBuZwk4MTQ%3D&auto=format",
                    "mediaId": "3nO-shKnBV18",
                    "width": 1390,
                    "height": 341,
                    "mimeType": "image/png"
                },
                "caption": "COVID-19 mRNA vaccines",
                "source": "Source: Example1"
            }
        },

How would I go about replacing these entries properly?
In the end, since I have multiple entries like these, I'm thinking about storing the value on a variable and iterate, image by image, all the replacements that need to be made, but I just can't get select the whole string so far, only directly replacing parts of it.

Thanks

答案1

得分: 1

你可以使用 regexp_replace

update document_revisions set data = regexp_replace(data::text, 
 ''(https\://my\.)oldserver(\.com/api/v1/images/[\w\-]+\.[a-z]+\?id\=(?:[^"]+)*)'', 
 ''newserver'', ''g')::jsonb

查看示例

英文:

You can use regexp_replace:

update document_revisions set data = regexp_replace(data::text, 
 '(https\://my\.)oldserver(\.com/api/v1/images/[\w\-]+\.[a-z]+\?id\=(?:[^"]+)*)', 
 'newserver', 'g')::jsonb

See fiddle

huangapple
  • 本文由 发表于 2023年5月22日 22:45:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76307359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定