Mysql 使用REGEXP动态更改URL字符串的SQL查询

Mysql 使用REGEXP动态更改URL字符串的SQL查询,mysql,sql,regex,mariadb,Mysql,Sql,Regex,Mariadb,我的名为“post”的DB表如下所示 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/i

我的名为“post”的DB表如下所示

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的ENRTIE,它们不应更改

现在我必须更改每个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并不难,但我必须添加静态文件扩展名,在我的例子中,.png位于URL字符串的末尾

编辑//

最后,我的DB表应该是这样的

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用户。

您可以在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://或'http://
的地方查找匹配项,然后是
任何字符,然后是
/images/
,然后是
任何数字,4或5次,然后是
[,或字母或空格,然后是任何字符

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

regexp使用一个捕获组捕获数字之前的所有内容,并将其替换为自身以及
.png

给出您的示例的结果: DBFiddle

编辑:上述内容在MariaDB中不起作用 由于您使用的是MariaDB 10,请查看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

编辑您的问题并显示所有行的最终结果。我刚刚做了编辑是否可能有2个或更多的[LINK]..[/LINK]发生在一条消息中?特别是当一条消息正确,而另一条消息不正确时…最后,我的DB表应该是这样的:
id=7
中的链接为什么没有更新?@Akina,是的,可能出现多个[link]-标记。id=7没有更新,因为“id部分”最后一行的URL有6位数字,其中查询应该只更改末尾有4或5位数字的条目。感谢@dustytrash的回答。在新行,我得到了一个例子,在查询后:[LINK][URL]$1.png[/URL][/LINK]。此外,我看到一些URL的URL ID和[/LINK]之间有一个空格-标签。它也会触动包含此类URL的[LINK]的条目。太棒了,它对大多数条目都有效。现在我看到一些格式为[URL=”的条目没有改变。我编辑了我的问题并添加了一个示例。是的,它有效!!你是我的英雄,非常感谢@dustytrash
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]).*';