1

I need to mass-replace a string in my forum database via phpMyAdmin, but I don't know how.

I want to replace:

[member=1]username[/member]

with

[url=https://www.website.xxx/index.php?action=profile;u=1]username[/url]

My problem is with that "1", which changes with each username.

Here is what I have tried:

UPDATE messages
SET body = replace(body,"[member=","[url=https://www.website.xxx/index.php?action=profile;u=")
cybersam
  • 63,203
  • 6
  • 53
  • 76
  • Does this answer your question? [How to do a regular expression replace in MySQL?](https://stackoverflow.com/questions/986826/how-to-do-a-regular-expression-replace-in-mysql) – Phil Mar 24 '23 at 00:50

1 Answers1

0

I don't have a MySQL installed here but I read up it works there as well, as Phil said, you need regex

To read about regex replace, go here To check how it works, go here and paste what you need to find and replace.

Although it is not clear what part exactly you want to replace

The whole thing with number after '=' [member=ANY_NUMBER]username[/member] or replace the ANY_NUMBER with [...]username[/url]?

If you need to replace the whole thing use this regex \[member=\d\]username\[\/member\] the \d is a number, but only one, if it is multiple digits, do \d+

so it would be

UPDATE messages 
SET body = 
  REGEXP_REPLACE(body, 
    '\[member=\d+\]username\[\/member\]', 
    'REPLACE_WITH_TEXT_HERE'
  )

Before actually updating, do run a select to verify it works as intended

if you need to replace the ANY_NUMBER part for anything else so it would be

Warning: db engines can reference capture groups differently, so check with select that it works before doing an update

UPDATE messages 
SET body = 
  REGEXP_REPLACE(body, 
    '(\[member=)\d+(\]username\[\/member\])', 
    '\1REPLACE_WITH_TEXT_HERE\2'
  )

The \1 and \2 are important and are called capture groups, we can divide a search in parts and use that as we want, for ex do \2\1 to reverse order.

Before actually updating, do run a select to verify it works as intended

UPDATE:new information

eliminate everything but the username, i.e., change this: [member=ANY_NUMBER]username[/member] to this: username.

That is a subset of described up there

So we need to find [member=ANY_NUMBER]username[/member] and get only the username I strongly advise you to look up what regex is, how to use it to replace and how to use captive groups.

This is regex to 'select' user from body \[member=\d+\](.+)\[\/member\]

How it works? It finds anything that looks like [member=ANY_NUMBER] then it looks to find [/member], and ANYTHING in between is captured by a capture group (.+) it literally says here: any sting of any chars of any length.

This is how it works: link to what you see https://regex101.com/r/HSd2WA/1 how it works image

update SQL:

UPDATE messages 
SET body = 
  REGEXP_REPLACE(body, 
    '\[member=\d+\](.+)\[\/member\]', 
    '\1'
  )

VERIFYING THAT IT WORKS

How? Do a select, that's how!

I created a table with ID and body, populated with what you can find in the regex link.

 id |                             body
----+---------------------------------------------------------------
  1 | sdfdfsfdsasfda[member=1]merof[/member]safdfdsafdsfdsa
  2 | sfdafdsafdsa[member=10]Fraga Campos[/member]sfdasfda
  3 | asdffdsafdsa[member=300]Campos[/member]afsfdsafds
  4 | dfsvnosringtpoeringer[member=10000]Fraga[/member]sdafdsdfgdfg
  5 | dsfggfdsgfds[member=10000]dude[/member]
  6 | sdgf[member=10000]user[/member]sfd
  7 | dfg[member=10000]00)_09824;sd-2=3#_@$JFuser[/member]df
(7 rows)

Now I do a select the '!!!\1!!!' is there replace value, where \1 is capture group, I added !!! for it to be easier to see.

select REGEXP_REPLACE(body, 
    '\[member=\d+\](.+)\[\/member\]', 
    '!!!\1!!!'
  )
from messages  

Gives me

                regexp_replace
----------------------------------------------
 sdfdfsfdsasfda!!!merof!!!safdfdsafdsfdsa
 sfdafdsafdsa!!!Fraga Campos!!!sfdasfda
 asdffdsafdsa!!!Campos!!!afsfdsafds
 dfsvnosringtpoeringer!!!Fraga!!!sdafdsdfgdfg
 dsfggfdsgfds!!!dude!!!
 sdgf!!!user!!!sfd
 dfg!!!00)_09824;sd-2=3#_@$JFuser!!!df
(7 rows)
merof
  • 121
  • 7
  • Thank you for your reply, merof. Given I don't understand all the nuances of the code and I don't want to mess with the database, what I would like to do is this: eliminate everything but the username, i.e., change this: [member=ANY_NUMBER]username[/member] to this: username. I thought of doing this in two steps, first replacing [member=ANY_NUMBER] with a space (or nothing) and then do the same with [/member]. I hope this was more clear. – Fraga Campos Mar 25 '23 at 17:23
  • You should be more explicit and provide an example data for answers to be more on point, I could've written 1/3 of it ended up to be. do read up on regex, it sometimes saves you hours of work – merof Mar 26 '23 at 15:08
  • I don't think the command is efficient. Here's what happens when I do a select: https://i.imgur.com/icsS3fu.png – Fraga Campos Mar 30 '23 at 00:47
  • That's what happens when there is no data to work on. Please add at least three example entries. as for `efficient`, I think you mean `does not do the thing` first, as I can see there's some edge cases, and, more importantly, what engine is it? MySql? – merof Apr 03 '23 at 03:21
  • The server has 10.3.38-MariaDB with PHP: 7.4.33. I'm trying to make this change with phpMyAdmin. I used this code in phpMyAdmin and it changes many, many strings where there's not even a username or member strings. For example: "[size]." becomes "[siz1l]." - "Oi, povo. :good:" becomes "Oi, povo. :goo1>T+", etc. So, it seems something is not working. :( – Fraga Campos Apr 12 '23 at 16:24