【问题标题】:SQL Query with REGEXP to change URL strings dynamically使用 REGEXP 动态更改 URL 字符串的 SQL 查询
【发布时间】:2020-02-27 12:19:09
【问题描述】:

我的名为“post”的数据库表如下所示

id   |   message
----------------
1    |   test
2    |   Here is your image link: [LINK]https://example.com/images/1234[/LINK] You can view it now.
3    |   some strings
4    |   Here is your image link: [LINK]https://example.com/images/5678[/LINK] You can view it now.
5    |   [LINK]no correct url[/LINK]
6    |   [LINK][IMG]https://example.com/images/9123[/IMG][/LINK]
7    |   [LINK]https://example.com/images/912364[/LINK]
8    |   [LINK]Some text https://example.com/images/23456 Text again[/LINK]
9    |   [URL="https://example.com/images/10796"]

因此,并非每个消息行都包含一个 url,也不是每个带有 [LINK] 标记的消息都包含一个正确的 url。还有一些条目的 ID 较长,不应更改。

现在我必须更改 ID 长度在 4 到 5 个字符之间的每个条目:

https://example.com/images/1234
https://example.com/images/5678

到那种格式 -> 添加文件扩展名

https://example.com/images/1234.png
https://example.com/images/5678.png

所以“ID”等于文件名。仅替换 URL 并不难,但我必须添加静态文件扩展名,在我的例子中是 URL 字符串末尾的“.png”。

编辑//

最后,我的数据库表应该是这样的

id   |   message
----------------
1    |   test
2    |   Here is your image link: [LINK]https://example.com/images/1234.png[/LINK] You can view it now.
3    |   some strings
4    |   Here is your image link: [LINK]https://example.com/images/5678.png[/LINK] You can view it now.
5    |   [LINK]no correct url[/LINK]
6    |   [LINK][IMG]https://example.com/images/9123.png[/IMG][/LINK]
7    |   [LINK]https://example.com/images/912364[/LINK]
8    |   [LINK]Some text https://example.com/images/23456.png Text again[/LINK]
9    |   [URL="https://example.com/images/10796.png"]

仅在“URL-ID”有 4 位或 5 位数字且 URL 匹配的情况下将文件扩展名添加到 URL。

我绝对不是有经验的 SQL 用户。

【问题讨论】:

  • 。 .编辑您的问题并显示您想要所有行的最终结果。
  • 我刚刚进行了编辑
  • 是否有可能在一条消息中出现 2 个或多个 [LINK]..[/LINK]?尤其是当一个正确而另一个不正确时......
  • 最后,我的数据库表应该是这样的 为什么id=7中的链接没有更新?
  • @Akina,是的,有可能出现多个 [LINK]-标签。 id=7 没有更新,因为 URL 末尾的“ID 部分”有 6 位数字,其中查询应该只更改末尾有 4 或 5 位数字的条目。

标签: mysql sql regex mariadb


【解决方案1】:

您可以在 MySQL 8.0 及更高版本中使用正则表达式:

SELECT message AS original, REGEXP_REPLACE(message, '((http://|https://).*/images/[0-9]+)', '$1.png') AS new
  FROM Post 
  WHERE message REGEXP '.*(http://|https://).*/images/([0-9]{4,5})(?![0-9]).*'

where 子句仅在找到https:// or 'http:// 的位置查找匹配项,然后是any characters,然后是/images/,然后是any number, 4 or 5 times,然后是[, or a letter or space,然后是任何字符。

(?![0-9]) 很重要,因为.* 将匹配任何字符,包括数字。因此,如果没有它,将找到 6 个以上数字的匹配项。它基本上意味着“除了数字之外的任何东西”。

正则表达式使用捕获组捕获数字之前的所有内容,并将其替换为自身,加上.png

以您为例的结果:

Here is your image link: [LINK]https://example.com/images/1234.png[/LINK] You can view it now.
Here is your image link: [LINK]https://example.com/images/5678.png[/LINK] You can view it now.
[LINK][IMG]https://example.com/images/9123.png[/IMG][/LINK]
[LINK]Some text https://example.com/images/23456.png Text again[/LINK]
[URL="https://example.com/images/10796.png"]

DBFiddle

https://www.db-fiddle.com/#&togetherjs=4qC2I51yju

编辑:以上在 MariaDB 中不起作用

因为你使用的是 MariaDB 10,看一下 REGEXP_REPLACE 函数的参考:https://mariadb.com/kb/en/regexp_replace/

您需要使用\\1,而不是$1。因此,如果您使用的是 MariaDB,请将 $1.png 替换为 \\1.png

用于更新的最终查询:

UPDATE Post SET message = REGEXP_REPLACE(message, '((http://|https://).*/images/[0-9]+)', '$1.png')
      WHERE message REGEXP '.*(http://|https://).*/images/([0-9]{4,5})(?!0-9]).*';

将 MariaDB 的 $1.png 更改为 \\1.png

【讨论】:

  • 感谢@dustytrash 的回答。例如,在新行上,我在查询后得到:[LINK][url]$1.png[/url] [/LINK]。此外,我看到,某些 URL 在 URL ID 和 [/LINK]-Tag 之间确实有一个空格。
  • 它也会触及包含此类 URL 的 [LINK]example.com/images/146818616741951.png[/LINK] 的条目
  • 太好了,它适用于大多数条目。现在我看到了一些格式 [URL="example.com/images/10796"] 没有改变。我编辑了我的问题并添加了一个示例。
  • 是的,它成功了!你是我的英雄,非常感谢@dustytrash
猜你喜欢
  • 2021-05-25
  • 2012-06-16
  • 2013-06-17
  • 1970-01-01
  • 2018-08-07
  • 2011-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多