How to do a regular expression replace in MySQL?












447















I have a table with ~500k rows; varchar(255) UTF8 column filename contains a file name;



I'm trying to strip out various strange characters out of the filename - thought I'd use a character class: [^a-zA-Z0-9()_ .-]



Now, is there a function in MySQL that lets you replace through a regular expression? I'm looking for a similar functionality to REPLACE() function - simplified example follows:



SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');

Output: "-tackover-low"


I know about REGEXP/RLIKE, but those only check if there is a match, not what the match is.



(I could do a "SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .-]'" from a PHP script, do a preg_replace and then "UPDATE foo ... WHERE pkey_id=...", but that looks like a last-resort slow & ugly hack)










share|improve this question




















  • 7





    It's a feature request since 2007: bugs.mysql.com/bug.php?id=27389. If you really want this feature, log in and click "Affects me" button. Hopefully it will get enough votes.

    – TMS
    Mar 7 '14 at 17:19






  • 4





    @Tomas: I have done that...in 2009, when I was looking around for it. Since there has been zero progress on it - apparently it's not such an important feature. (btw Postgres has it: stackoverflow.com/questions/11722995/… )

    – Piskvor
    Mar 9 '14 at 16:45






  • 1





    Related, simpler, version of this question: stackoverflow.com/questions/6942973/…

    – Kzqai
    Mar 12 '14 at 21:30






  • 1





    @Kzqai: Good to know, thanks; I'll edit this into the question.

    – Piskvor
    Mar 14 '14 at 9:49






  • 2





    I've created regexp_split (function + procedure) & regexp_replace, which are implemented with REGEXP operator. For simple lookups, it will do the trick. You may find it here - so, this is the way with MySQL stored code, no UDF. If you'll find some bugs, which are not covered by known limitations - feel free to open the issue.

    – Alma Do
    Jun 5 '14 at 8:51


















447















I have a table with ~500k rows; varchar(255) UTF8 column filename contains a file name;



I'm trying to strip out various strange characters out of the filename - thought I'd use a character class: [^a-zA-Z0-9()_ .-]



Now, is there a function in MySQL that lets you replace through a regular expression? I'm looking for a similar functionality to REPLACE() function - simplified example follows:



SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');

Output: "-tackover-low"


I know about REGEXP/RLIKE, but those only check if there is a match, not what the match is.



(I could do a "SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .-]'" from a PHP script, do a preg_replace and then "UPDATE foo ... WHERE pkey_id=...", but that looks like a last-resort slow & ugly hack)










share|improve this question




















  • 7





    It's a feature request since 2007: bugs.mysql.com/bug.php?id=27389. If you really want this feature, log in and click "Affects me" button. Hopefully it will get enough votes.

    – TMS
    Mar 7 '14 at 17:19






  • 4





    @Tomas: I have done that...in 2009, when I was looking around for it. Since there has been zero progress on it - apparently it's not such an important feature. (btw Postgres has it: stackoverflow.com/questions/11722995/… )

    – Piskvor
    Mar 9 '14 at 16:45






  • 1





    Related, simpler, version of this question: stackoverflow.com/questions/6942973/…

    – Kzqai
    Mar 12 '14 at 21:30






  • 1





    @Kzqai: Good to know, thanks; I'll edit this into the question.

    – Piskvor
    Mar 14 '14 at 9:49






  • 2





    I've created regexp_split (function + procedure) & regexp_replace, which are implemented with REGEXP operator. For simple lookups, it will do the trick. You may find it here - so, this is the way with MySQL stored code, no UDF. If you'll find some bugs, which are not covered by known limitations - feel free to open the issue.

    – Alma Do
    Jun 5 '14 at 8:51
















447












447








447


83






I have a table with ~500k rows; varchar(255) UTF8 column filename contains a file name;



I'm trying to strip out various strange characters out of the filename - thought I'd use a character class: [^a-zA-Z0-9()_ .-]



Now, is there a function in MySQL that lets you replace through a regular expression? I'm looking for a similar functionality to REPLACE() function - simplified example follows:



SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');

Output: "-tackover-low"


I know about REGEXP/RLIKE, but those only check if there is a match, not what the match is.



(I could do a "SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .-]'" from a PHP script, do a preg_replace and then "UPDATE foo ... WHERE pkey_id=...", but that looks like a last-resort slow & ugly hack)










share|improve this question
















I have a table with ~500k rows; varchar(255) UTF8 column filename contains a file name;



I'm trying to strip out various strange characters out of the filename - thought I'd use a character class: [^a-zA-Z0-9()_ .-]



Now, is there a function in MySQL that lets you replace through a regular expression? I'm looking for a similar functionality to REPLACE() function - simplified example follows:



SELECT REPLACE('stackowerflow', 'ower', 'over');

Output: "stackoverflow"

/* does something like this exist? */
SELECT X_REG_REPLACE('Stackoverflow','/[A-Zf]/','-');

Output: "-tackover-low"


I know about REGEXP/RLIKE, but those only check if there is a match, not what the match is.



(I could do a "SELECT pkey_id,filename FROM foo WHERE filename RLIKE '[^a-zA-Z0-9()_ .-]'" from a PHP script, do a preg_replace and then "UPDATE foo ... WHERE pkey_id=...", but that looks like a last-resort slow & ugly hack)







mysql regex mysql-udf






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 23 '17 at 12:10









Community

11




11










asked Jun 12 '09 at 14:08









PiskvorPiskvor

71.9k41153208




71.9k41153208








  • 7





    It's a feature request since 2007: bugs.mysql.com/bug.php?id=27389. If you really want this feature, log in and click "Affects me" button. Hopefully it will get enough votes.

    – TMS
    Mar 7 '14 at 17:19






  • 4





    @Tomas: I have done that...in 2009, when I was looking around for it. Since there has been zero progress on it - apparently it's not such an important feature. (btw Postgres has it: stackoverflow.com/questions/11722995/… )

    – Piskvor
    Mar 9 '14 at 16:45






  • 1





    Related, simpler, version of this question: stackoverflow.com/questions/6942973/…

    – Kzqai
    Mar 12 '14 at 21:30






  • 1





    @Kzqai: Good to know, thanks; I'll edit this into the question.

    – Piskvor
    Mar 14 '14 at 9:49






  • 2





    I've created regexp_split (function + procedure) & regexp_replace, which are implemented with REGEXP operator. For simple lookups, it will do the trick. You may find it here - so, this is the way with MySQL stored code, no UDF. If you'll find some bugs, which are not covered by known limitations - feel free to open the issue.

    – Alma Do
    Jun 5 '14 at 8:51
















  • 7





    It's a feature request since 2007: bugs.mysql.com/bug.php?id=27389. If you really want this feature, log in and click "Affects me" button. Hopefully it will get enough votes.

    – TMS
    Mar 7 '14 at 17:19






  • 4





    @Tomas: I have done that...in 2009, when I was looking around for it. Since there has been zero progress on it - apparently it's not such an important feature. (btw Postgres has it: stackoverflow.com/questions/11722995/… )

    – Piskvor
    Mar 9 '14 at 16:45






  • 1





    Related, simpler, version of this question: stackoverflow.com/questions/6942973/…

    – Kzqai
    Mar 12 '14 at 21:30






  • 1





    @Kzqai: Good to know, thanks; I'll edit this into the question.

    – Piskvor
    Mar 14 '14 at 9:49






  • 2





    I've created regexp_split (function + procedure) & regexp_replace, which are implemented with REGEXP operator. For simple lookups, it will do the trick. You may find it here - so, this is the way with MySQL stored code, no UDF. If you'll find some bugs, which are not covered by known limitations - feel free to open the issue.

    – Alma Do
    Jun 5 '14 at 8:51










7




7





It's a feature request since 2007: bugs.mysql.com/bug.php?id=27389. If you really want this feature, log in and click "Affects me" button. Hopefully it will get enough votes.

– TMS
Mar 7 '14 at 17:19





It's a feature request since 2007: bugs.mysql.com/bug.php?id=27389. If you really want this feature, log in and click "Affects me" button. Hopefully it will get enough votes.

– TMS
Mar 7 '14 at 17:19




4




4





@Tomas: I have done that...in 2009, when I was looking around for it. Since there has been zero progress on it - apparently it's not such an important feature. (btw Postgres has it: stackoverflow.com/questions/11722995/… )

– Piskvor
Mar 9 '14 at 16:45





@Tomas: I have done that...in 2009, when I was looking around for it. Since there has been zero progress on it - apparently it's not such an important feature. (btw Postgres has it: stackoverflow.com/questions/11722995/… )

– Piskvor
Mar 9 '14 at 16:45




1




1





Related, simpler, version of this question: stackoverflow.com/questions/6942973/…

– Kzqai
Mar 12 '14 at 21:30





Related, simpler, version of this question: stackoverflow.com/questions/6942973/…

– Kzqai
Mar 12 '14 at 21:30




1




1





@Kzqai: Good to know, thanks; I'll edit this into the question.

– Piskvor
Mar 14 '14 at 9:49





@Kzqai: Good to know, thanks; I'll edit this into the question.

– Piskvor
Mar 14 '14 at 9:49




2




2





I've created regexp_split (function + procedure) & regexp_replace, which are implemented with REGEXP operator. For simple lookups, it will do the trick. You may find it here - so, this is the way with MySQL stored code, no UDF. If you'll find some bugs, which are not covered by known limitations - feel free to open the issue.

– Alma Do
Jun 5 '14 at 8:51







I've created regexp_split (function + procedure) & regexp_replace, which are implemented with REGEXP operator. For simple lookups, it will do the trick. You may find it here - so, this is the way with MySQL stored code, no UDF. If you'll find some bugs, which are not covered by known limitations - feel free to open the issue.

– Alma Do
Jun 5 '14 at 8:51














10 Answers
10






active

oldest

votes


















24














MySQL 8.0+ you could use natively REGEXP_REPLACE.



12.5.2 Regular Expressions:




REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])



Replaces occurrences in the string expr that match the regular expression specified by the pattern pat with the replacement string repl, and returns the resulting string. If expr, pat, or repl is NULL, the return value is NULL.




and Regular expression support:




Previously, MySQL used the Henry Spencer regular expression library to support regular expression operators (REGEXP, RLIKE).



Regular expression support has been reimplemented using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe. The REGEXP_LIKE() function performs regular expression matching in the manner of the REGEXP and RLIKE operators, which now are synonyms for that function. In addition, the REGEXP_INSTR(), REGEXP_REPLACE(), and REGEXP_SUBSTR() functions are available to find match positions and perform substring substitution and extraction, respectively.




SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
-- Output:
-tackover-low


DBFiddle Demo






share|improve this answer

































    137














    No.



    But if you have access to your server, you could use a user defined function (UDF) like mysql-udf-regexp.



    EDIT: MySQL 8.0+ you could use natively REGEXP_REPLACE. More in answer above






    share|improve this answer





















    • 3





      REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

      – Piskvor
      Jun 12 '09 at 15:34






    • 14





      Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

      – lkraav
      Feb 20 '12 at 1:44






    • 3





      MySQL itself does not support multi-byte characters with its RegEx features.

      – Brad
      Mar 20 '13 at 20:53






    • 4





      Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

      – Jonathan
      Dec 5 '13 at 23:58






    • 2





      @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

      – gillyspy
      Feb 9 '14 at 19:46



















    113














    Use MariaDB instead. It has a function



    REGEXP_REPLACE(col, regexp, replace)


    See MariaDB docs and PCRE Regular expression enhancements



    Note that you can use regexp grouping as well (I found that very useful):



    SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\2 - \1 - \3')


    returns



    over - stack - flow





    share|improve this answer





















    • 4





      Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

      – Piskvor
      Oct 3 '14 at 14:09






    • 10





      this is from mariadb 10

      – Nick
      Oct 7 '14 at 17:02






    • 5





      For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

      – Josiah
      Aug 11 '16 at 12:01






    • 8





      Changing an entire platform is hardly a realistic solution.

      – David Baucum
      Nov 29 '17 at 22:15






    • 2





      @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

      – Benvorth
      Nov 30 '17 at 6:15



















    105














    My brute force method to get this to work was just:




    1. Dump the table - mysqldump -u user -p database table > dump.sql

    2. Find and replace a couple patterns - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} ;, There are obviously other perl regeular expressions you could perform on the file as well.

    3. Import the table - mysqlimport -u user -p database table < dump.sql


    If you want to make sure the string isn't elsewhere in your dataset, run a few regular expressions to make sure they all occur in a similar environment. It's also not that tough to create a backup before you run a replace, in case you accidentally destroy something that loses depth of information.






    share|improve this answer





















    • 28





      Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

      – Piskvor
      Feb 27 '12 at 5:33






    • 10





      Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

      – speshak
      Mar 23 '12 at 16:17






    • 2





      can work if the the replace can't broke the SQL itself.

      – Moshe L
      May 4 '12 at 9:28






    • 32





      Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

      – Raul Luna
      May 15 '14 at 15:50






    • 5





      Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

      – eggmatters
      Jun 9 '15 at 16:56



















    40














    I recently wrote a MySQL function to replace strings using regular expressions. You could find my post at the following location:



    http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/



    Here is the function code:



    DELIMITER $$

    CREATE FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
    RETURNS VARCHAR(1000)
    DETERMINISTIC
    BEGIN
    DECLARE temp VARCHAR(1000);
    DECLARE ch VARCHAR(1);
    DECLARE i INT;
    SET i = 1;
    SET temp = '';
    IF original REGEXP pattern THEN
    loop_label: LOOP
    IF i>CHAR_LENGTH(original) THEN
    LEAVE loop_label;
    END IF;
    SET ch = SUBSTRING(original,i,1);
    IF NOT ch REGEXP pattern THEN
    SET temp = CONCAT(temp,ch);
    ELSE
    SET temp = CONCAT(temp,replacement);
    END IF;
    SET i=i+1;
    END LOOP;
    ELSE
    SET temp = original;
    END IF;
    RETURN temp;
    END$$

    DELIMITER ;


    Example execution:



    mysql> select regex_replace('[^a-zA-Z0-9-]','','2my test3_text-to. check \ my- sql (regular) ,expressions ._,');





    share|improve this answer





















    • 7





      It also only works on single characters..

      – Jay Taylor
      Jan 5 '12 at 21:24






    • 20





      I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

      – Jason
      Feb 6 '12 at 23:15






    • 2





      It would be more helpful to actually include code in you answer instead of posting a naked link.

      – phobie
      Nov 17 '15 at 9:38






    • 2





      Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

      – Izzy
      Apr 2 '16 at 18:33











    • @phobie someone else did that in this answer – just as a reference in case the link dies ;)

      – Izzy
      Apr 2 '16 at 18:35



















    31














    we solve this problem without using regex
    this query replace only exact match string.



    update employee set
    employee_firstname =
    trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))


    Example:




    emp_id employee_firstname



    1 jay



    2 jay ajay



    3 jay




    After executing query result:




    emp_id employee_firstname



    1 abc



    2 abc ajay



    3 abc







    share|improve this answer





















    • 4





      I have no idea why this answer had no votes but this is works perfectly.

      – James Drummond
      Dec 25 '15 at 13:53











    • @yellowmelon what are the two pairs of double quotes for?

      – codecowboy
      Mar 4 '16 at 12:31






    • 3





      He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

      – Slam
      Apr 21 '16 at 20:29






    • 1





      Looks like a pretty solid workaround for word replacement!

      – Sean the Bean
      Oct 5 '17 at 13:32



















    13














    I'm happy to report that since this question was asked, now there is a satisfactory answer! Take a look at this terrific package:



    https://github.com/mysqludf/lib_mysqludf_preg



    Sample SQL:



    SELECT PREG_REPLACE('/(.*?)(fox)/' , 'dog' , 'the quick brown fox' ) AS demo;


    I found the package from this blog post as linked on this question.






    share|improve this answer





















    • 1





      how would you update a value in a table?

      – codecowboy
      Mar 4 '16 at 12:29











    • @dotancohen that would be also my question!

      – kidata
      Oct 18 '16 at 9:31





















    8














    UPDATE 2: A useful set of regex functions including REGEXP_REPLACE have now been provided in MySQL 8.0. This renders reading on unnecessary unless you're constrained to using an earlier version.





    UPDATE 1: Have now made this into a blog post: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html





    The following expands upon the function provided by Rasika Godawatte but trawls through all necessary substrings rather than just testing single characters:



    -- ------------------------------------------------------------------------------------
    -- USAGE
    -- ------------------------------------------------------------------------------------
    -- SELECT reg_replace(<subject>,
    -- <pattern>,
    -- <replacement>,
    -- <greedy>,
    -- <minMatchLen>,
    -- <maxMatchLen>);
    -- where:
    -- <subject> is the string to look in for doing the replacements
    -- <pattern> is the regular expression to match against
    -- <replacement> is the replacement string
    -- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
    -- <minMatchLen> specifies the minimum match length
    -- <maxMatchLen> specifies the maximum match length
    -- (minMatchLen and maxMatchLen are used to improve efficiency but are
    -- optional and can be set to 0 or NULL if not known/required)
    -- Example:
    -- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
    DROP FUNCTION IF EXISTS reg_replace;
    DELIMITER //
    CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
    replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
    RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
    DECLARE result, subStr, usePattern VARCHAR(21845);
    DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
    IF subject REGEXP pattern THEN
    SET result = '';
    -- Sanitize input parameter values
    SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
    SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
    CHAR_LENGTH(subject), maxMatchLen);
    -- Set the pattern to use to match an entire string rather than part of a string
    SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
    SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
    -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
    IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
    SET startPos = 1, startInc = 1;
    -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
    -- to the min or max match length from the end (depending on "greedy" flag).
    ELSEIF greedy THEN
    SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
    ELSE
    SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
    END IF;
    WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
    AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
    AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
    AND !(RIGHT(pattern, 1) = '$'
    AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
    -- Set start length to maximum if matching greedily or pattern ends with $.
    -- Otherwise set starting length to the minimum match length.
    IF greedy OR RIGHT(pattern, 1) = '$' THEN
    SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
    ELSE
    SET len = minMatchLen, lenInc = 1;
    END IF;
    SET prevStartPos = startPos;
    lenLoop: WHILE len >= 1 AND len <= maxMatchLen
    AND startPos + len - 1 <= CHAR_LENGTH(subject)
    AND !(RIGHT(pattern, 1) = '$'
    AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
    SET subStr = SUBSTRING(subject, startPos, len);
    IF subStr REGEXP usePattern THEN
    SET result = IF(startInc = 1,
    CONCAT(result, replacement), CONCAT(replacement, result));
    SET startPos = startPos + startInc * len;
    LEAVE lenLoop;
    END IF;
    SET len = len + lenInc;
    END WHILE;
    IF (startPos = prevStartPos) THEN
    SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
    CONCAT(SUBSTRING(subject, startPos, 1), result));
    SET startPos = startPos + startInc;
    END IF;
    END WHILE;
    IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
    SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
    ELSEIF startInc = -1 AND startPos >= 1 THEN
    SET result = CONCAT(LEFT(subject, startPos), result);
    END IF;
    ELSE
    SET result = subject;
    END IF;
    RETURN result;
    END//
    DELIMITER ;


    Demo



    Rextester Demo



    Limitations




    1. This method is of course going to take a while when the subject
      string is large. Update: Have now added minimum and maximum match length parameters for improved efficiency when these are known (zero = unknown/unlimited).

    2. It won't allow substitution of backreferences (e.g. 1, 2
      etc.) to replace capturing groups. If this functionality is needed, please see this answer which attempts to provide a workaround by updating the function to allow a secondary find and replace within each found match (at the expense of increased complexity).

    3. If ^and/or $ is used in the pattern, they must be at the very start and very end respectively - e.g. patterns such as (^start|end$) are not supported.

    4. There is a "greedy" flag to specify whether the overall matching should be greedy or non-greedy. Combining greedy and lazy matching within a single regular expression (e.g. a.*?b.*) is not supported.


    Usage Examples



    The function has been used to answer the following StackOverflow questions:




    • How to count words in MySQL / regular expression
      replacer?

    • How to extract the nth word and count word occurrences in a MySQL
      string?

    • How to extract two consecutive digits from a text field in
      MySQL?

    • How to remove all non-alpha numeric characters from a string in
      MySQL?

    • How to replace every other instance of a particular character in a MySQL
      string?






    share|improve this answer





















    • 1





      Wow! Is perfect!

      – OscarR
      Aug 3 '18 at 11:47



















    7














    You 'can' do it ... but it's not very wise ... this is about as daring as I'll try ... as far as full RegEx support your much better off using perl or the like.



    UPDATE db.tbl
    SET column =
    CASE
    WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'
    THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
    END
    WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'





    share|improve this answer





















    • 1





      No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

      – Ryan Shillington
      Oct 3 '12 at 17:14






    • 1





      @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

      – Eddie B
      Oct 3 '12 at 17:21






    • 1





      Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

      – Eddie B
      Oct 10 '12 at 23:33








    • 2





      @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

      – Eddie B
      Apr 29 '13 at 18:16






    • 2





      I guess there's a difference between "not wise" and "incorrect".

      – jmilloy
      Sep 26 '13 at 14:32



















    4














    We can use IF condition in SELECT query as below:



    Suppose that for anything with "ABC","ABC1","ABC2","ABC3",..., we want to replace with "ABC" then using REGEXP and IF() condition in the SELECT query, we can achieve this.



    Syntax:



    SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
    FROM table1
    WHERE column_name LIKE 'ABC%';


    Example:



    SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');





    share|improve this answer


























    • Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

      – Piskvor
      Dec 1 '14 at 8:38










    protected by Samuel Liew Oct 5 '15 at 9:21



    Thank you for your interest in this question.
    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



    Would you like to answer one of these unanswered questions instead?














    10 Answers
    10






    active

    oldest

    votes








    10 Answers
    10






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    24














    MySQL 8.0+ you could use natively REGEXP_REPLACE.



    12.5.2 Regular Expressions:




    REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])



    Replaces occurrences in the string expr that match the regular expression specified by the pattern pat with the replacement string repl, and returns the resulting string. If expr, pat, or repl is NULL, the return value is NULL.




    and Regular expression support:




    Previously, MySQL used the Henry Spencer regular expression library to support regular expression operators (REGEXP, RLIKE).



    Regular expression support has been reimplemented using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe. The REGEXP_LIKE() function performs regular expression matching in the manner of the REGEXP and RLIKE operators, which now are synonyms for that function. In addition, the REGEXP_INSTR(), REGEXP_REPLACE(), and REGEXP_SUBSTR() functions are available to find match positions and perform substring substitution and extraction, respectively.




    SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
    -- Output:
    -tackover-low


    DBFiddle Demo






    share|improve this answer






























      24














      MySQL 8.0+ you could use natively REGEXP_REPLACE.



      12.5.2 Regular Expressions:




      REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])



      Replaces occurrences in the string expr that match the regular expression specified by the pattern pat with the replacement string repl, and returns the resulting string. If expr, pat, or repl is NULL, the return value is NULL.




      and Regular expression support:




      Previously, MySQL used the Henry Spencer regular expression library to support regular expression operators (REGEXP, RLIKE).



      Regular expression support has been reimplemented using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe. The REGEXP_LIKE() function performs regular expression matching in the manner of the REGEXP and RLIKE operators, which now are synonyms for that function. In addition, the REGEXP_INSTR(), REGEXP_REPLACE(), and REGEXP_SUBSTR() functions are available to find match positions and perform substring substitution and extraction, respectively.




      SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
      -- Output:
      -tackover-low


      DBFiddle Demo






      share|improve this answer




























        24












        24








        24







        MySQL 8.0+ you could use natively REGEXP_REPLACE.



        12.5.2 Regular Expressions:




        REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])



        Replaces occurrences in the string expr that match the regular expression specified by the pattern pat with the replacement string repl, and returns the resulting string. If expr, pat, or repl is NULL, the return value is NULL.




        and Regular expression support:




        Previously, MySQL used the Henry Spencer regular expression library to support regular expression operators (REGEXP, RLIKE).



        Regular expression support has been reimplemented using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe. The REGEXP_LIKE() function performs regular expression matching in the manner of the REGEXP and RLIKE operators, which now are synonyms for that function. In addition, the REGEXP_INSTR(), REGEXP_REPLACE(), and REGEXP_SUBSTR() functions are available to find match positions and perform substring substitution and extraction, respectively.




        SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
        -- Output:
        -tackover-low


        DBFiddle Demo






        share|improve this answer















        MySQL 8.0+ you could use natively REGEXP_REPLACE.



        12.5.2 Regular Expressions:




        REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])



        Replaces occurrences in the string expr that match the regular expression specified by the pattern pat with the replacement string repl, and returns the resulting string. If expr, pat, or repl is NULL, the return value is NULL.




        and Regular expression support:




        Previously, MySQL used the Henry Spencer regular expression library to support regular expression operators (REGEXP, RLIKE).



        Regular expression support has been reimplemented using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe. The REGEXP_LIKE() function performs regular expression matching in the manner of the REGEXP and RLIKE operators, which now are synonyms for that function. In addition, the REGEXP_INSTR(), REGEXP_REPLACE(), and REGEXP_SUBSTR() functions are available to find match positions and perform substring substitution and extraction, respectively.




        SELECT REGEXP_REPLACE('Stackoverflow','[A-Zf]','-',1,0,'c'); 
        -- Output:
        -tackover-low


        DBFiddle Demo







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited May 6 '18 at 5:06

























        answered Apr 19 '18 at 16:07









        Lukasz SzozdaLukasz Szozda

        79.1k1061105




        79.1k1061105

























            137














            No.



            But if you have access to your server, you could use a user defined function (UDF) like mysql-udf-regexp.



            EDIT: MySQL 8.0+ you could use natively REGEXP_REPLACE. More in answer above






            share|improve this answer





















            • 3





              REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

              – Piskvor
              Jun 12 '09 at 15:34






            • 14





              Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

              – lkraav
              Feb 20 '12 at 1:44






            • 3





              MySQL itself does not support multi-byte characters with its RegEx features.

              – Brad
              Mar 20 '13 at 20:53






            • 4





              Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

              – Jonathan
              Dec 5 '13 at 23:58






            • 2





              @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

              – gillyspy
              Feb 9 '14 at 19:46
















            137














            No.



            But if you have access to your server, you could use a user defined function (UDF) like mysql-udf-regexp.



            EDIT: MySQL 8.0+ you could use natively REGEXP_REPLACE. More in answer above






            share|improve this answer





















            • 3





              REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

              – Piskvor
              Jun 12 '09 at 15:34






            • 14





              Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

              – lkraav
              Feb 20 '12 at 1:44






            • 3





              MySQL itself does not support multi-byte characters with its RegEx features.

              – Brad
              Mar 20 '13 at 20:53






            • 4





              Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

              – Jonathan
              Dec 5 '13 at 23:58






            • 2





              @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

              – gillyspy
              Feb 9 '14 at 19:46














            137












            137








            137







            No.



            But if you have access to your server, you could use a user defined function (UDF) like mysql-udf-regexp.



            EDIT: MySQL 8.0+ you could use natively REGEXP_REPLACE. More in answer above






            share|improve this answer















            No.



            But if you have access to your server, you could use a user defined function (UDF) like mysql-udf-regexp.



            EDIT: MySQL 8.0+ you could use natively REGEXP_REPLACE. More in answer above







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 30 '18 at 12:22









            Mladen Janjetovic

            6,93564659




            6,93564659










            answered Jun 12 '09 at 14:16









            Jeremy SteinJeremy Stein

            12.6k155975




            12.6k155975








            • 3





              REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

              – Piskvor
              Jun 12 '09 at 15:34






            • 14





              Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

              – lkraav
              Feb 20 '12 at 1:44






            • 3





              MySQL itself does not support multi-byte characters with its RegEx features.

              – Brad
              Mar 20 '13 at 20:53






            • 4





              Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

              – Jonathan
              Dec 5 '13 at 23:58






            • 2





              @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

              – gillyspy
              Feb 9 '14 at 19:46














            • 3





              REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

              – Piskvor
              Jun 12 '09 at 15:34






            • 14





              Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

              – lkraav
              Feb 20 '12 at 1:44






            • 3





              MySQL itself does not support multi-byte characters with its RegEx features.

              – Brad
              Mar 20 '13 at 20:53






            • 4





              Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

              – Jonathan
              Dec 5 '13 at 23:58






            • 2





              @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

              – gillyspy
              Feb 9 '14 at 19:46








            3




            3





            REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

            – Piskvor
            Jun 12 '09 at 15:34





            REGEXP_REPLACE as a User Defined Function? Looks promising, will look into it. Thanks!

            – Piskvor
            Jun 12 '09 at 15:34




            14




            14





            Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

            – lkraav
            Feb 20 '12 at 1:44





            Unfortunately mysql-udf-regexp doesn't seem to have support for multibyte characters. regexp_replace('äöõü', 'ä', '') returns a long numeric string instead of real text.

            – lkraav
            Feb 20 '12 at 1:44




            3




            3





            MySQL itself does not support multi-byte characters with its RegEx features.

            – Brad
            Mar 20 '13 at 20:53





            MySQL itself does not support multi-byte characters with its RegEx features.

            – Brad
            Mar 20 '13 at 20:53




            4




            4





            Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

            – Jonathan
            Dec 5 '13 at 23:58





            Windows users: The UDF Library linked here doesn't seem to have good windows support. The windows installation method outlined did not work well for me.

            – Jonathan
            Dec 5 '13 at 23:58




            2




            2





            @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

            – gillyspy
            Feb 9 '14 at 19:46





            @lkraav you should try out the lib_mysqludf_preg library below as it works great. This the verbose version as it returns a blob by default and I don't know if you have a multibyte charset as your default: select cast( T.R as char) COLLATE utf8_unicode_ci from (select preg_replace('/ä/', '', 'öõüä') R ) T

            – gillyspy
            Feb 9 '14 at 19:46











            113














            Use MariaDB instead. It has a function



            REGEXP_REPLACE(col, regexp, replace)


            See MariaDB docs and PCRE Regular expression enhancements



            Note that you can use regexp grouping as well (I found that very useful):



            SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\2 - \1 - \3')


            returns



            over - stack - flow





            share|improve this answer





















            • 4





              Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

              – Piskvor
              Oct 3 '14 at 14:09






            • 10





              this is from mariadb 10

              – Nick
              Oct 7 '14 at 17:02






            • 5





              For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

              – Josiah
              Aug 11 '16 at 12:01






            • 8





              Changing an entire platform is hardly a realistic solution.

              – David Baucum
              Nov 29 '17 at 22:15






            • 2





              @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

              – Benvorth
              Nov 30 '17 at 6:15
















            113














            Use MariaDB instead. It has a function



            REGEXP_REPLACE(col, regexp, replace)


            See MariaDB docs and PCRE Regular expression enhancements



            Note that you can use regexp grouping as well (I found that very useful):



            SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\2 - \1 - \3')


            returns



            over - stack - flow





            share|improve this answer





















            • 4





              Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

              – Piskvor
              Oct 3 '14 at 14:09






            • 10





              this is from mariadb 10

              – Nick
              Oct 7 '14 at 17:02






            • 5





              For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

              – Josiah
              Aug 11 '16 at 12:01






            • 8





              Changing an entire platform is hardly a realistic solution.

              – David Baucum
              Nov 29 '17 at 22:15






            • 2





              @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

              – Benvorth
              Nov 30 '17 at 6:15














            113












            113








            113







            Use MariaDB instead. It has a function



            REGEXP_REPLACE(col, regexp, replace)


            See MariaDB docs and PCRE Regular expression enhancements



            Note that you can use regexp grouping as well (I found that very useful):



            SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\2 - \1 - \3')


            returns



            over - stack - flow





            share|improve this answer















            Use MariaDB instead. It has a function



            REGEXP_REPLACE(col, regexp, replace)


            See MariaDB docs and PCRE Regular expression enhancements



            Note that you can use regexp grouping as well (I found that very useful):



            SELECT REGEXP_REPLACE("stackoverflow", "(stack)(over)(flow)", '\2 - \1 - \3')


            returns



            over - stack - flow






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 3 '16 at 3:42









            CJ Dennis

            2,18312037




            2,18312037










            answered Oct 3 '14 at 13:11









            BenvorthBenvorth

            4,56462952




            4,56462952








            • 4





              Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

              – Piskvor
              Oct 3 '14 at 14:09






            • 10





              this is from mariadb 10

              – Nick
              Oct 7 '14 at 17:02






            • 5





              For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

              – Josiah
              Aug 11 '16 at 12:01






            • 8





              Changing an entire platform is hardly a realistic solution.

              – David Baucum
              Nov 29 '17 at 22:15






            • 2





              @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

              – Benvorth
              Nov 30 '17 at 6:15














            • 4





              Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

              – Piskvor
              Oct 3 '14 at 14:09






            • 10





              this is from mariadb 10

              – Nick
              Oct 7 '14 at 17:02






            • 5





              For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

              – Josiah
              Aug 11 '16 at 12:01






            • 8





              Changing an entire platform is hardly a realistic solution.

              – David Baucum
              Nov 29 '17 at 22:15






            • 2





              @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

              – Benvorth
              Nov 30 '17 at 6:15








            4




            4





            Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

            – Piskvor
            Oct 3 '14 at 14:09





            Niiiice! Even more so because we have already migrated to it for unrelated reasons. Thanks for the tip :)

            – Piskvor
            Oct 3 '14 at 14:09




            10




            10





            this is from mariadb 10

            – Nick
            Oct 7 '14 at 17:02





            this is from mariadb 10

            – Nick
            Oct 7 '14 at 17:02




            5




            5





            For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

            – Josiah
            Aug 11 '16 at 12:01





            For the next time I need it, here's syntax for changing a whole column: UPDATE table SET Name = REGEXP_REPLACE(Name, "-2$", "\1") This removes -2 from abcxyz-2 from a whole column at once.

            – Josiah
            Aug 11 '16 at 12:01




            8




            8





            Changing an entire platform is hardly a realistic solution.

            – David Baucum
            Nov 29 '17 at 22:15





            Changing an entire platform is hardly a realistic solution.

            – David Baucum
            Nov 29 '17 at 22:15




            2




            2





            @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

            – Benvorth
            Nov 30 '17 at 6:15





            @DavidBaucum MariaDB is a drop-in replacement for MySQL. So it is no "change of platform" but more like choosing a different airline for the same trip

            – Benvorth
            Nov 30 '17 at 6:15











            105














            My brute force method to get this to work was just:




            1. Dump the table - mysqldump -u user -p database table > dump.sql

            2. Find and replace a couple patterns - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} ;, There are obviously other perl regeular expressions you could perform on the file as well.

            3. Import the table - mysqlimport -u user -p database table < dump.sql


            If you want to make sure the string isn't elsewhere in your dataset, run a few regular expressions to make sure they all occur in a similar environment. It's also not that tough to create a backup before you run a replace, in case you accidentally destroy something that loses depth of information.






            share|improve this answer





















            • 28





              Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

              – Piskvor
              Feb 27 '12 at 5:33






            • 10





              Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

              – speshak
              Mar 23 '12 at 16:17






            • 2





              can work if the the replace can't broke the SQL itself.

              – Moshe L
              May 4 '12 at 9:28






            • 32





              Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

              – Raul Luna
              May 15 '14 at 15:50






            • 5





              Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

              – eggmatters
              Jun 9 '15 at 16:56
















            105














            My brute force method to get this to work was just:




            1. Dump the table - mysqldump -u user -p database table > dump.sql

            2. Find and replace a couple patterns - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} ;, There are obviously other perl regeular expressions you could perform on the file as well.

            3. Import the table - mysqlimport -u user -p database table < dump.sql


            If you want to make sure the string isn't elsewhere in your dataset, run a few regular expressions to make sure they all occur in a similar environment. It's also not that tough to create a backup before you run a replace, in case you accidentally destroy something that loses depth of information.






            share|improve this answer





















            • 28





              Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

              – Piskvor
              Feb 27 '12 at 5:33






            • 10





              Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

              – speshak
              Mar 23 '12 at 16:17






            • 2





              can work if the the replace can't broke the SQL itself.

              – Moshe L
              May 4 '12 at 9:28






            • 32





              Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

              – Raul Luna
              May 15 '14 at 15:50






            • 5





              Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

              – eggmatters
              Jun 9 '15 at 16:56














            105












            105








            105







            My brute force method to get this to work was just:




            1. Dump the table - mysqldump -u user -p database table > dump.sql

            2. Find and replace a couple patterns - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} ;, There are obviously other perl regeular expressions you could perform on the file as well.

            3. Import the table - mysqlimport -u user -p database table < dump.sql


            If you want to make sure the string isn't elsewhere in your dataset, run a few regular expressions to make sure they all occur in a similar environment. It's also not that tough to create a backup before you run a replace, in case you accidentally destroy something that loses depth of information.






            share|improve this answer















            My brute force method to get this to work was just:




            1. Dump the table - mysqldump -u user -p database table > dump.sql

            2. Find and replace a couple patterns - find /path/to/dump.sql -type f -exec sed -i 's/old_string/new_string/g' {} ;, There are obviously other perl regeular expressions you could perform on the file as well.

            3. Import the table - mysqlimport -u user -p database table < dump.sql


            If you want to make sure the string isn't elsewhere in your dataset, run a few regular expressions to make sure they all occur in a similar environment. It's also not that tough to create a backup before you run a replace, in case you accidentally destroy something that loses depth of information.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Apr 19 '18 at 22:29

























            answered Feb 26 '12 at 19:52









            Ryan WardRyan Ward

            3,15052943




            3,15052943








            • 28





              Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

              – Piskvor
              Feb 27 '12 at 5:33






            • 10





              Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

              – speshak
              Mar 23 '12 at 16:17






            • 2





              can work if the the replace can't broke the SQL itself.

              – Moshe L
              May 4 '12 at 9:28






            • 32





              Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

              – Raul Luna
              May 15 '14 at 15:50






            • 5





              Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

              – eggmatters
              Jun 9 '15 at 16:56














            • 28





              Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

              – Piskvor
              Feb 27 '12 at 5:33






            • 10





              Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

              – speshak
              Mar 23 '12 at 16:17






            • 2





              can work if the the replace can't broke the SQL itself.

              – Moshe L
              May 4 '12 at 9:28






            • 32





              Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

              – Raul Luna
              May 15 '14 at 15:50






            • 5





              Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

              – eggmatters
              Jun 9 '15 at 16:56








            28




            28





            Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

            – Piskvor
            Feb 27 '12 at 5:33





            Okay, that should work, too; I didn't consider an offline replace. Nice out-of-the-box thinking there!

            – Piskvor
            Feb 27 '12 at 5:33




            10




            10





            Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

            – speshak
            Mar 23 '12 at 16:17





            Seems strange to me that you'd use find like that, I would shorten the command to sed -i 's/old_string/new_string/g' /path/to/dump.sql

            – speshak
            Mar 23 '12 at 16:17




            2




            2





            can work if the the replace can't broke the SQL itself.

            – Moshe L
            May 4 '12 at 9:28





            can work if the the replace can't broke the SQL itself.

            – Moshe L
            May 4 '12 at 9:28




            32




            32





            Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

            – Raul Luna
            May 15 '14 at 15:50





            Very risky, and unpractical with big data sets, or with referential integrity in place: for remove the data and then insert it again you will have to turn referential integrity off, leaving in practice your database off also.

            – Raul Luna
            May 15 '14 at 15:50




            5




            5





            Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

            – eggmatters
            Jun 9 '15 at 16:56





            Having used this method in the past, I aggre with Raul, this is very risky. You need to be absolutely certain as well, that your string is not elswhere in your dataset.

            – eggmatters
            Jun 9 '15 at 16:56











            40














            I recently wrote a MySQL function to replace strings using regular expressions. You could find my post at the following location:



            http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/



            Here is the function code:



            DELIMITER $$

            CREATE FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
            RETURNS VARCHAR(1000)
            DETERMINISTIC
            BEGIN
            DECLARE temp VARCHAR(1000);
            DECLARE ch VARCHAR(1);
            DECLARE i INT;
            SET i = 1;
            SET temp = '';
            IF original REGEXP pattern THEN
            loop_label: LOOP
            IF i>CHAR_LENGTH(original) THEN
            LEAVE loop_label;
            END IF;
            SET ch = SUBSTRING(original,i,1);
            IF NOT ch REGEXP pattern THEN
            SET temp = CONCAT(temp,ch);
            ELSE
            SET temp = CONCAT(temp,replacement);
            END IF;
            SET i=i+1;
            END LOOP;
            ELSE
            SET temp = original;
            END IF;
            RETURN temp;
            END$$

            DELIMITER ;


            Example execution:



            mysql> select regex_replace('[^a-zA-Z0-9-]','','2my test3_text-to. check \ my- sql (regular) ,expressions ._,');





            share|improve this answer





















            • 7





              It also only works on single characters..

              – Jay Taylor
              Jan 5 '12 at 21:24






            • 20





              I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

              – Jason
              Feb 6 '12 at 23:15






            • 2





              It would be more helpful to actually include code in you answer instead of posting a naked link.

              – phobie
              Nov 17 '15 at 9:38






            • 2





              Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

              – Izzy
              Apr 2 '16 at 18:33











            • @phobie someone else did that in this answer – just as a reference in case the link dies ;)

              – Izzy
              Apr 2 '16 at 18:35
















            40














            I recently wrote a MySQL function to replace strings using regular expressions. You could find my post at the following location:



            http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/



            Here is the function code:



            DELIMITER $$

            CREATE FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
            RETURNS VARCHAR(1000)
            DETERMINISTIC
            BEGIN
            DECLARE temp VARCHAR(1000);
            DECLARE ch VARCHAR(1);
            DECLARE i INT;
            SET i = 1;
            SET temp = '';
            IF original REGEXP pattern THEN
            loop_label: LOOP
            IF i>CHAR_LENGTH(original) THEN
            LEAVE loop_label;
            END IF;
            SET ch = SUBSTRING(original,i,1);
            IF NOT ch REGEXP pattern THEN
            SET temp = CONCAT(temp,ch);
            ELSE
            SET temp = CONCAT(temp,replacement);
            END IF;
            SET i=i+1;
            END LOOP;
            ELSE
            SET temp = original;
            END IF;
            RETURN temp;
            END$$

            DELIMITER ;


            Example execution:



            mysql> select regex_replace('[^a-zA-Z0-9-]','','2my test3_text-to. check \ my- sql (regular) ,expressions ._,');





            share|improve this answer





















            • 7





              It also only works on single characters..

              – Jay Taylor
              Jan 5 '12 at 21:24






            • 20





              I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

              – Jason
              Feb 6 '12 at 23:15






            • 2





              It would be more helpful to actually include code in you answer instead of posting a naked link.

              – phobie
              Nov 17 '15 at 9:38






            • 2





              Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

              – Izzy
              Apr 2 '16 at 18:33











            • @phobie someone else did that in this answer – just as a reference in case the link dies ;)

              – Izzy
              Apr 2 '16 at 18:35














            40












            40








            40







            I recently wrote a MySQL function to replace strings using regular expressions. You could find my post at the following location:



            http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/



            Here is the function code:



            DELIMITER $$

            CREATE FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
            RETURNS VARCHAR(1000)
            DETERMINISTIC
            BEGIN
            DECLARE temp VARCHAR(1000);
            DECLARE ch VARCHAR(1);
            DECLARE i INT;
            SET i = 1;
            SET temp = '';
            IF original REGEXP pattern THEN
            loop_label: LOOP
            IF i>CHAR_LENGTH(original) THEN
            LEAVE loop_label;
            END IF;
            SET ch = SUBSTRING(original,i,1);
            IF NOT ch REGEXP pattern THEN
            SET temp = CONCAT(temp,ch);
            ELSE
            SET temp = CONCAT(temp,replacement);
            END IF;
            SET i=i+1;
            END LOOP;
            ELSE
            SET temp = original;
            END IF;
            RETURN temp;
            END$$

            DELIMITER ;


            Example execution:



            mysql> select regex_replace('[^a-zA-Z0-9-]','','2my test3_text-to. check \ my- sql (regular) ,expressions ._,');





            share|improve this answer















            I recently wrote a MySQL function to replace strings using regular expressions. You could find my post at the following location:



            http://techras.wordpress.com/2011/06/02/regex-replace-for-mysql/



            Here is the function code:



            DELIMITER $$

            CREATE FUNCTION `regex_replace`(pattern VARCHAR(1000),replacement VARCHAR(1000),original VARCHAR(1000))
            RETURNS VARCHAR(1000)
            DETERMINISTIC
            BEGIN
            DECLARE temp VARCHAR(1000);
            DECLARE ch VARCHAR(1);
            DECLARE i INT;
            SET i = 1;
            SET temp = '';
            IF original REGEXP pattern THEN
            loop_label: LOOP
            IF i>CHAR_LENGTH(original) THEN
            LEAVE loop_label;
            END IF;
            SET ch = SUBSTRING(original,i,1);
            IF NOT ch REGEXP pattern THEN
            SET temp = CONCAT(temp,ch);
            ELSE
            SET temp = CONCAT(temp,replacement);
            END IF;
            SET i=i+1;
            END LOOP;
            ELSE
            SET temp = original;
            END IF;
            RETURN temp;
            END$$

            DELIMITER ;


            Example execution:



            mysql> select regex_replace('[^a-zA-Z0-9-]','','2my test3_text-to. check \ my- sql (regular) ,expressions ._,');






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 5 '16 at 7:22









            joshweir

            1,83121133




            1,83121133










            answered Jun 2 '11 at 15:16









            rasika godawatterasika godawatte

            46542




            46542








            • 7





              It also only works on single characters..

              – Jay Taylor
              Jan 5 '12 at 21:24






            • 20





              I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

              – Jason
              Feb 6 '12 at 23:15






            • 2





              It would be more helpful to actually include code in you answer instead of posting a naked link.

              – phobie
              Nov 17 '15 at 9:38






            • 2





              Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

              – Izzy
              Apr 2 '16 at 18:33











            • @phobie someone else did that in this answer – just as a reference in case the link dies ;)

              – Izzy
              Apr 2 '16 at 18:35














            • 7





              It also only works on single characters..

              – Jay Taylor
              Jan 5 '12 at 21:24






            • 20





              I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

              – Jason
              Feb 6 '12 at 23:15






            • 2





              It would be more helpful to actually include code in you answer instead of posting a naked link.

              – phobie
              Nov 17 '15 at 9:38






            • 2





              Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

              – Izzy
              Apr 2 '16 at 18:33











            • @phobie someone else did that in this answer – just as a reference in case the link dies ;)

              – Izzy
              Apr 2 '16 at 18:35








            7




            7





            It also only works on single characters..

            – Jay Taylor
            Jan 5 '12 at 21:24





            It also only works on single characters..

            – Jay Taylor
            Jan 5 '12 at 21:24




            20




            20





            I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

            – Jason
            Feb 6 '12 at 23:15





            I'll just reinforce the above point: this function replaces characters that match a single-character expression. It says above that it is used "to repalce strings using regular expressions", and that can be a little misleading. It does its job, but it's not the job being asked for. (Not a complaint - it is just to save leading people down the wrong path)

            – Jason
            Feb 6 '12 at 23:15




            2




            2





            It would be more helpful to actually include code in you answer instead of posting a naked link.

            – phobie
            Nov 17 '15 at 9:38





            It would be more helpful to actually include code in you answer instead of posting a naked link.

            – phobie
            Nov 17 '15 at 9:38




            2




            2





            Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

            – Izzy
            Apr 2 '16 at 18:33





            Nice – but unfortunately doesn't deal with references like select regex_replace('.*(abc).*','1','noabcde') (returns 'noabcde', not 'abc').

            – Izzy
            Apr 2 '16 at 18:33













            @phobie someone else did that in this answer – just as a reference in case the link dies ;)

            – Izzy
            Apr 2 '16 at 18:35





            @phobie someone else did that in this answer – just as a reference in case the link dies ;)

            – Izzy
            Apr 2 '16 at 18:35











            31














            we solve this problem without using regex
            this query replace only exact match string.



            update employee set
            employee_firstname =
            trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))


            Example:




            emp_id employee_firstname



            1 jay



            2 jay ajay



            3 jay




            After executing query result:




            emp_id employee_firstname



            1 abc



            2 abc ajay



            3 abc







            share|improve this answer





















            • 4





              I have no idea why this answer had no votes but this is works perfectly.

              – James Drummond
              Dec 25 '15 at 13:53











            • @yellowmelon what are the two pairs of double quotes for?

              – codecowboy
              Mar 4 '16 at 12:31






            • 3





              He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

              – Slam
              Apr 21 '16 at 20:29






            • 1





              Looks like a pretty solid workaround for word replacement!

              – Sean the Bean
              Oct 5 '17 at 13:32
















            31














            we solve this problem without using regex
            this query replace only exact match string.



            update employee set
            employee_firstname =
            trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))


            Example:




            emp_id employee_firstname



            1 jay



            2 jay ajay



            3 jay




            After executing query result:




            emp_id employee_firstname



            1 abc



            2 abc ajay



            3 abc







            share|improve this answer





















            • 4





              I have no idea why this answer had no votes but this is works perfectly.

              – James Drummond
              Dec 25 '15 at 13:53











            • @yellowmelon what are the two pairs of double quotes for?

              – codecowboy
              Mar 4 '16 at 12:31






            • 3





              He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

              – Slam
              Apr 21 '16 at 20:29






            • 1





              Looks like a pretty solid workaround for word replacement!

              – Sean the Bean
              Oct 5 '17 at 13:32














            31












            31








            31







            we solve this problem without using regex
            this query replace only exact match string.



            update employee set
            employee_firstname =
            trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))


            Example:




            emp_id employee_firstname



            1 jay



            2 jay ajay



            3 jay




            After executing query result:




            emp_id employee_firstname



            1 abc



            2 abc ajay



            3 abc







            share|improve this answer















            we solve this problem without using regex
            this query replace only exact match string.



            update employee set
            employee_firstname =
            trim(REPLACE(concat(" ",employee_firstname," "),' jay ',' abc '))


            Example:




            emp_id employee_firstname



            1 jay



            2 jay ajay



            3 jay




            After executing query result:




            emp_id employee_firstname



            1 abc



            2 abc ajay



            3 abc








            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jul 21 '15 at 21:34









            chris85

            22.3k72342




            22.3k72342










            answered Dec 19 '14 at 5:07









            Jay PatelJay Patel

            32132




            32132








            • 4





              I have no idea why this answer had no votes but this is works perfectly.

              – James Drummond
              Dec 25 '15 at 13:53











            • @yellowmelon what are the two pairs of double quotes for?

              – codecowboy
              Mar 4 '16 at 12:31






            • 3





              He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

              – Slam
              Apr 21 '16 at 20:29






            • 1





              Looks like a pretty solid workaround for word replacement!

              – Sean the Bean
              Oct 5 '17 at 13:32














            • 4





              I have no idea why this answer had no votes but this is works perfectly.

              – James Drummond
              Dec 25 '15 at 13:53











            • @yellowmelon what are the two pairs of double quotes for?

              – codecowboy
              Mar 4 '16 at 12:31






            • 3





              He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

              – Slam
              Apr 21 '16 at 20:29






            • 1





              Looks like a pretty solid workaround for word replacement!

              – Sean the Bean
              Oct 5 '17 at 13:32








            4




            4





            I have no idea why this answer had no votes but this is works perfectly.

            – James Drummond
            Dec 25 '15 at 13:53





            I have no idea why this answer had no votes but this is works perfectly.

            – James Drummond
            Dec 25 '15 at 13:53













            @yellowmelon what are the two pairs of double quotes for?

            – codecowboy
            Mar 4 '16 at 12:31





            @yellowmelon what are the two pairs of double quotes for?

            – codecowboy
            Mar 4 '16 at 12:31




            3




            3





            He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

            – Slam
            Apr 21 '16 at 20:29





            He's padding the employeename with spaces before and after. This allows him to search-replace for (space)employeename(space), which avoids catching the employeename "jay" if its part of a larger string "ajay." Then he trims the spaces out when done.

            – Slam
            Apr 21 '16 at 20:29




            1




            1





            Looks like a pretty solid workaround for word replacement!

            – Sean the Bean
            Oct 5 '17 at 13:32





            Looks like a pretty solid workaround for word replacement!

            – Sean the Bean
            Oct 5 '17 at 13:32











            13














            I'm happy to report that since this question was asked, now there is a satisfactory answer! Take a look at this terrific package:



            https://github.com/mysqludf/lib_mysqludf_preg



            Sample SQL:



            SELECT PREG_REPLACE('/(.*?)(fox)/' , 'dog' , 'the quick brown fox' ) AS demo;


            I found the package from this blog post as linked on this question.






            share|improve this answer





















            • 1





              how would you update a value in a table?

              – codecowboy
              Mar 4 '16 at 12:29











            • @dotancohen that would be also my question!

              – kidata
              Oct 18 '16 at 9:31


















            13














            I'm happy to report that since this question was asked, now there is a satisfactory answer! Take a look at this terrific package:



            https://github.com/mysqludf/lib_mysqludf_preg



            Sample SQL:



            SELECT PREG_REPLACE('/(.*?)(fox)/' , 'dog' , 'the quick brown fox' ) AS demo;


            I found the package from this blog post as linked on this question.






            share|improve this answer





















            • 1





              how would you update a value in a table?

              – codecowboy
              Mar 4 '16 at 12:29











            • @dotancohen that would be also my question!

              – kidata
              Oct 18 '16 at 9:31
















            13












            13








            13







            I'm happy to report that since this question was asked, now there is a satisfactory answer! Take a look at this terrific package:



            https://github.com/mysqludf/lib_mysqludf_preg



            Sample SQL:



            SELECT PREG_REPLACE('/(.*?)(fox)/' , 'dog' , 'the quick brown fox' ) AS demo;


            I found the package from this blog post as linked on this question.






            share|improve this answer















            I'm happy to report that since this question was asked, now there is a satisfactory answer! Take a look at this terrific package:



            https://github.com/mysqludf/lib_mysqludf_preg



            Sample SQL:



            SELECT PREG_REPLACE('/(.*?)(fox)/' , 'dog' , 'the quick brown fox' ) AS demo;


            I found the package from this blog post as linked on this question.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 23 '17 at 12:18









            Community

            11




            11










            answered Nov 13 '13 at 14:51









            dotancohendotancohen

            14.6k1899149




            14.6k1899149








            • 1





              how would you update a value in a table?

              – codecowboy
              Mar 4 '16 at 12:29











            • @dotancohen that would be also my question!

              – kidata
              Oct 18 '16 at 9:31
















            • 1





              how would you update a value in a table?

              – codecowboy
              Mar 4 '16 at 12:29











            • @dotancohen that would be also my question!

              – kidata
              Oct 18 '16 at 9:31










            1




            1





            how would you update a value in a table?

            – codecowboy
            Mar 4 '16 at 12:29





            how would you update a value in a table?

            – codecowboy
            Mar 4 '16 at 12:29













            @dotancohen that would be also my question!

            – kidata
            Oct 18 '16 at 9:31







            @dotancohen that would be also my question!

            – kidata
            Oct 18 '16 at 9:31













            8














            UPDATE 2: A useful set of regex functions including REGEXP_REPLACE have now been provided in MySQL 8.0. This renders reading on unnecessary unless you're constrained to using an earlier version.





            UPDATE 1: Have now made this into a blog post: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html





            The following expands upon the function provided by Rasika Godawatte but trawls through all necessary substrings rather than just testing single characters:



            -- ------------------------------------------------------------------------------------
            -- USAGE
            -- ------------------------------------------------------------------------------------
            -- SELECT reg_replace(<subject>,
            -- <pattern>,
            -- <replacement>,
            -- <greedy>,
            -- <minMatchLen>,
            -- <maxMatchLen>);
            -- where:
            -- <subject> is the string to look in for doing the replacements
            -- <pattern> is the regular expression to match against
            -- <replacement> is the replacement string
            -- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
            -- <minMatchLen> specifies the minimum match length
            -- <maxMatchLen> specifies the maximum match length
            -- (minMatchLen and maxMatchLen are used to improve efficiency but are
            -- optional and can be set to 0 or NULL if not known/required)
            -- Example:
            -- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
            DROP FUNCTION IF EXISTS reg_replace;
            DELIMITER //
            CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
            replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
            RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
            DECLARE result, subStr, usePattern VARCHAR(21845);
            DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
            IF subject REGEXP pattern THEN
            SET result = '';
            -- Sanitize input parameter values
            SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
            SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
            CHAR_LENGTH(subject), maxMatchLen);
            -- Set the pattern to use to match an entire string rather than part of a string
            SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
            SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
            -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
            IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
            SET startPos = 1, startInc = 1;
            -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
            -- to the min or max match length from the end (depending on "greedy" flag).
            ELSEIF greedy THEN
            SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
            ELSE
            SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
            END IF;
            WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
            AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
            AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
            -- Set start length to maximum if matching greedily or pattern ends with $.
            -- Otherwise set starting length to the minimum match length.
            IF greedy OR RIGHT(pattern, 1) = '$' THEN
            SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
            ELSE
            SET len = minMatchLen, lenInc = 1;
            END IF;
            SET prevStartPos = startPos;
            lenLoop: WHILE len >= 1 AND len <= maxMatchLen
            AND startPos + len - 1 <= CHAR_LENGTH(subject)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
            SET subStr = SUBSTRING(subject, startPos, len);
            IF subStr REGEXP usePattern THEN
            SET result = IF(startInc = 1,
            CONCAT(result, replacement), CONCAT(replacement, result));
            SET startPos = startPos + startInc * len;
            LEAVE lenLoop;
            END IF;
            SET len = len + lenInc;
            END WHILE;
            IF (startPos = prevStartPos) THEN
            SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
            CONCAT(SUBSTRING(subject, startPos, 1), result));
            SET startPos = startPos + startInc;
            END IF;
            END WHILE;
            IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
            SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
            ELSEIF startInc = -1 AND startPos >= 1 THEN
            SET result = CONCAT(LEFT(subject, startPos), result);
            END IF;
            ELSE
            SET result = subject;
            END IF;
            RETURN result;
            END//
            DELIMITER ;


            Demo



            Rextester Demo



            Limitations




            1. This method is of course going to take a while when the subject
              string is large. Update: Have now added minimum and maximum match length parameters for improved efficiency when these are known (zero = unknown/unlimited).

            2. It won't allow substitution of backreferences (e.g. 1, 2
              etc.) to replace capturing groups. If this functionality is needed, please see this answer which attempts to provide a workaround by updating the function to allow a secondary find and replace within each found match (at the expense of increased complexity).

            3. If ^and/or $ is used in the pattern, they must be at the very start and very end respectively - e.g. patterns such as (^start|end$) are not supported.

            4. There is a "greedy" flag to specify whether the overall matching should be greedy or non-greedy. Combining greedy and lazy matching within a single regular expression (e.g. a.*?b.*) is not supported.


            Usage Examples



            The function has been used to answer the following StackOverflow questions:




            • How to count words in MySQL / regular expression
              replacer?

            • How to extract the nth word and count word occurrences in a MySQL
              string?

            • How to extract two consecutive digits from a text field in
              MySQL?

            • How to remove all non-alpha numeric characters from a string in
              MySQL?

            • How to replace every other instance of a particular character in a MySQL
              string?






            share|improve this answer





















            • 1





              Wow! Is perfect!

              – OscarR
              Aug 3 '18 at 11:47
















            8














            UPDATE 2: A useful set of regex functions including REGEXP_REPLACE have now been provided in MySQL 8.0. This renders reading on unnecessary unless you're constrained to using an earlier version.





            UPDATE 1: Have now made this into a blog post: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html





            The following expands upon the function provided by Rasika Godawatte but trawls through all necessary substrings rather than just testing single characters:



            -- ------------------------------------------------------------------------------------
            -- USAGE
            -- ------------------------------------------------------------------------------------
            -- SELECT reg_replace(<subject>,
            -- <pattern>,
            -- <replacement>,
            -- <greedy>,
            -- <minMatchLen>,
            -- <maxMatchLen>);
            -- where:
            -- <subject> is the string to look in for doing the replacements
            -- <pattern> is the regular expression to match against
            -- <replacement> is the replacement string
            -- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
            -- <minMatchLen> specifies the minimum match length
            -- <maxMatchLen> specifies the maximum match length
            -- (minMatchLen and maxMatchLen are used to improve efficiency but are
            -- optional and can be set to 0 or NULL if not known/required)
            -- Example:
            -- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
            DROP FUNCTION IF EXISTS reg_replace;
            DELIMITER //
            CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
            replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
            RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
            DECLARE result, subStr, usePattern VARCHAR(21845);
            DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
            IF subject REGEXP pattern THEN
            SET result = '';
            -- Sanitize input parameter values
            SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
            SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
            CHAR_LENGTH(subject), maxMatchLen);
            -- Set the pattern to use to match an entire string rather than part of a string
            SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
            SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
            -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
            IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
            SET startPos = 1, startInc = 1;
            -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
            -- to the min or max match length from the end (depending on "greedy" flag).
            ELSEIF greedy THEN
            SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
            ELSE
            SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
            END IF;
            WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
            AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
            AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
            -- Set start length to maximum if matching greedily or pattern ends with $.
            -- Otherwise set starting length to the minimum match length.
            IF greedy OR RIGHT(pattern, 1) = '$' THEN
            SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
            ELSE
            SET len = minMatchLen, lenInc = 1;
            END IF;
            SET prevStartPos = startPos;
            lenLoop: WHILE len >= 1 AND len <= maxMatchLen
            AND startPos + len - 1 <= CHAR_LENGTH(subject)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
            SET subStr = SUBSTRING(subject, startPos, len);
            IF subStr REGEXP usePattern THEN
            SET result = IF(startInc = 1,
            CONCAT(result, replacement), CONCAT(replacement, result));
            SET startPos = startPos + startInc * len;
            LEAVE lenLoop;
            END IF;
            SET len = len + lenInc;
            END WHILE;
            IF (startPos = prevStartPos) THEN
            SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
            CONCAT(SUBSTRING(subject, startPos, 1), result));
            SET startPos = startPos + startInc;
            END IF;
            END WHILE;
            IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
            SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
            ELSEIF startInc = -1 AND startPos >= 1 THEN
            SET result = CONCAT(LEFT(subject, startPos), result);
            END IF;
            ELSE
            SET result = subject;
            END IF;
            RETURN result;
            END//
            DELIMITER ;


            Demo



            Rextester Demo



            Limitations




            1. This method is of course going to take a while when the subject
              string is large. Update: Have now added minimum and maximum match length parameters for improved efficiency when these are known (zero = unknown/unlimited).

            2. It won't allow substitution of backreferences (e.g. 1, 2
              etc.) to replace capturing groups. If this functionality is needed, please see this answer which attempts to provide a workaround by updating the function to allow a secondary find and replace within each found match (at the expense of increased complexity).

            3. If ^and/or $ is used in the pattern, they must be at the very start and very end respectively - e.g. patterns such as (^start|end$) are not supported.

            4. There is a "greedy" flag to specify whether the overall matching should be greedy or non-greedy. Combining greedy and lazy matching within a single regular expression (e.g. a.*?b.*) is not supported.


            Usage Examples



            The function has been used to answer the following StackOverflow questions:




            • How to count words in MySQL / regular expression
              replacer?

            • How to extract the nth word and count word occurrences in a MySQL
              string?

            • How to extract two consecutive digits from a text field in
              MySQL?

            • How to remove all non-alpha numeric characters from a string in
              MySQL?

            • How to replace every other instance of a particular character in a MySQL
              string?






            share|improve this answer





















            • 1





              Wow! Is perfect!

              – OscarR
              Aug 3 '18 at 11:47














            8












            8








            8







            UPDATE 2: A useful set of regex functions including REGEXP_REPLACE have now been provided in MySQL 8.0. This renders reading on unnecessary unless you're constrained to using an earlier version.





            UPDATE 1: Have now made this into a blog post: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html





            The following expands upon the function provided by Rasika Godawatte but trawls through all necessary substrings rather than just testing single characters:



            -- ------------------------------------------------------------------------------------
            -- USAGE
            -- ------------------------------------------------------------------------------------
            -- SELECT reg_replace(<subject>,
            -- <pattern>,
            -- <replacement>,
            -- <greedy>,
            -- <minMatchLen>,
            -- <maxMatchLen>);
            -- where:
            -- <subject> is the string to look in for doing the replacements
            -- <pattern> is the regular expression to match against
            -- <replacement> is the replacement string
            -- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
            -- <minMatchLen> specifies the minimum match length
            -- <maxMatchLen> specifies the maximum match length
            -- (minMatchLen and maxMatchLen are used to improve efficiency but are
            -- optional and can be set to 0 or NULL if not known/required)
            -- Example:
            -- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
            DROP FUNCTION IF EXISTS reg_replace;
            DELIMITER //
            CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
            replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
            RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
            DECLARE result, subStr, usePattern VARCHAR(21845);
            DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
            IF subject REGEXP pattern THEN
            SET result = '';
            -- Sanitize input parameter values
            SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
            SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
            CHAR_LENGTH(subject), maxMatchLen);
            -- Set the pattern to use to match an entire string rather than part of a string
            SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
            SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
            -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
            IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
            SET startPos = 1, startInc = 1;
            -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
            -- to the min or max match length from the end (depending on "greedy" flag).
            ELSEIF greedy THEN
            SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
            ELSE
            SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
            END IF;
            WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
            AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
            AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
            -- Set start length to maximum if matching greedily or pattern ends with $.
            -- Otherwise set starting length to the minimum match length.
            IF greedy OR RIGHT(pattern, 1) = '$' THEN
            SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
            ELSE
            SET len = minMatchLen, lenInc = 1;
            END IF;
            SET prevStartPos = startPos;
            lenLoop: WHILE len >= 1 AND len <= maxMatchLen
            AND startPos + len - 1 <= CHAR_LENGTH(subject)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
            SET subStr = SUBSTRING(subject, startPos, len);
            IF subStr REGEXP usePattern THEN
            SET result = IF(startInc = 1,
            CONCAT(result, replacement), CONCAT(replacement, result));
            SET startPos = startPos + startInc * len;
            LEAVE lenLoop;
            END IF;
            SET len = len + lenInc;
            END WHILE;
            IF (startPos = prevStartPos) THEN
            SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
            CONCAT(SUBSTRING(subject, startPos, 1), result));
            SET startPos = startPos + startInc;
            END IF;
            END WHILE;
            IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
            SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
            ELSEIF startInc = -1 AND startPos >= 1 THEN
            SET result = CONCAT(LEFT(subject, startPos), result);
            END IF;
            ELSE
            SET result = subject;
            END IF;
            RETURN result;
            END//
            DELIMITER ;


            Demo



            Rextester Demo



            Limitations




            1. This method is of course going to take a while when the subject
              string is large. Update: Have now added minimum and maximum match length parameters for improved efficiency when these are known (zero = unknown/unlimited).

            2. It won't allow substitution of backreferences (e.g. 1, 2
              etc.) to replace capturing groups. If this functionality is needed, please see this answer which attempts to provide a workaround by updating the function to allow a secondary find and replace within each found match (at the expense of increased complexity).

            3. If ^and/or $ is used in the pattern, they must be at the very start and very end respectively - e.g. patterns such as (^start|end$) are not supported.

            4. There is a "greedy" flag to specify whether the overall matching should be greedy or non-greedy. Combining greedy and lazy matching within a single regular expression (e.g. a.*?b.*) is not supported.


            Usage Examples



            The function has been used to answer the following StackOverflow questions:




            • How to count words in MySQL / regular expression
              replacer?

            • How to extract the nth word and count word occurrences in a MySQL
              string?

            • How to extract two consecutive digits from a text field in
              MySQL?

            • How to remove all non-alpha numeric characters from a string in
              MySQL?

            • How to replace every other instance of a particular character in a MySQL
              string?






            share|improve this answer















            UPDATE 2: A useful set of regex functions including REGEXP_REPLACE have now been provided in MySQL 8.0. This renders reading on unnecessary unless you're constrained to using an earlier version.





            UPDATE 1: Have now made this into a blog post: http://stevettt.blogspot.co.uk/2018/02/a-mysql-regular-expression-replace.html





            The following expands upon the function provided by Rasika Godawatte but trawls through all necessary substrings rather than just testing single characters:



            -- ------------------------------------------------------------------------------------
            -- USAGE
            -- ------------------------------------------------------------------------------------
            -- SELECT reg_replace(<subject>,
            -- <pattern>,
            -- <replacement>,
            -- <greedy>,
            -- <minMatchLen>,
            -- <maxMatchLen>);
            -- where:
            -- <subject> is the string to look in for doing the replacements
            -- <pattern> is the regular expression to match against
            -- <replacement> is the replacement string
            -- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
            -- <minMatchLen> specifies the minimum match length
            -- <maxMatchLen> specifies the maximum match length
            -- (minMatchLen and maxMatchLen are used to improve efficiency but are
            -- optional and can be set to 0 or NULL if not known/required)
            -- Example:
            -- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
            DROP FUNCTION IF EXISTS reg_replace;
            DELIMITER //
            CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
            replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
            RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
            DECLARE result, subStr, usePattern VARCHAR(21845);
            DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
            IF subject REGEXP pattern THEN
            SET result = '';
            -- Sanitize input parameter values
            SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
            SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
            CHAR_LENGTH(subject), maxMatchLen);
            -- Set the pattern to use to match an entire string rather than part of a string
            SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
            SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
            -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
            IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
            SET startPos = 1, startInc = 1;
            -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start pos
            -- to the min or max match length from the end (depending on "greedy" flag).
            ELSEIF greedy THEN
            SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
            ELSE
            SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
            END IF;
            WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
            AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
            AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
            -- Set start length to maximum if matching greedily or pattern ends with $.
            -- Otherwise set starting length to the minimum match length.
            IF greedy OR RIGHT(pattern, 1) = '$' THEN
            SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
            ELSE
            SET len = minMatchLen, lenInc = 1;
            END IF;
            SET prevStartPos = startPos;
            lenLoop: WHILE len >= 1 AND len <= maxMatchLen
            AND startPos + len - 1 <= CHAR_LENGTH(subject)
            AND !(RIGHT(pattern, 1) = '$'
            AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
            SET subStr = SUBSTRING(subject, startPos, len);
            IF subStr REGEXP usePattern THEN
            SET result = IF(startInc = 1,
            CONCAT(result, replacement), CONCAT(replacement, result));
            SET startPos = startPos + startInc * len;
            LEAVE lenLoop;
            END IF;
            SET len = len + lenInc;
            END WHILE;
            IF (startPos = prevStartPos) THEN
            SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
            CONCAT(SUBSTRING(subject, startPos, 1), result));
            SET startPos = startPos + startInc;
            END IF;
            END WHILE;
            IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
            SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
            ELSEIF startInc = -1 AND startPos >= 1 THEN
            SET result = CONCAT(LEFT(subject, startPos), result);
            END IF;
            ELSE
            SET result = subject;
            END IF;
            RETURN result;
            END//
            DELIMITER ;


            Demo



            Rextester Demo



            Limitations




            1. This method is of course going to take a while when the subject
              string is large. Update: Have now added minimum and maximum match length parameters for improved efficiency when these are known (zero = unknown/unlimited).

            2. It won't allow substitution of backreferences (e.g. 1, 2
              etc.) to replace capturing groups. If this functionality is needed, please see this answer which attempts to provide a workaround by updating the function to allow a secondary find and replace within each found match (at the expense of increased complexity).

            3. If ^and/or $ is used in the pattern, they must be at the very start and very end respectively - e.g. patterns such as (^start|end$) are not supported.

            4. There is a "greedy" flag to specify whether the overall matching should be greedy or non-greedy. Combining greedy and lazy matching within a single regular expression (e.g. a.*?b.*) is not supported.


            Usage Examples



            The function has been used to answer the following StackOverflow questions:




            • How to count words in MySQL / regular expression
              replacer?

            • How to extract the nth word and count word occurrences in a MySQL
              string?

            • How to extract two consecutive digits from a text field in
              MySQL?

            • How to remove all non-alpha numeric characters from a string in
              MySQL?

            • How to replace every other instance of a particular character in a MySQL
              string?







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Aug 3 '18 at 13:19

























            answered Jul 29 '16 at 13:49









            Steve ChambersSteve Chambers

            21.5k1194139




            21.5k1194139








            • 1





              Wow! Is perfect!

              – OscarR
              Aug 3 '18 at 11:47














            • 1





              Wow! Is perfect!

              – OscarR
              Aug 3 '18 at 11:47








            1




            1





            Wow! Is perfect!

            – OscarR
            Aug 3 '18 at 11:47





            Wow! Is perfect!

            – OscarR
            Aug 3 '18 at 11:47











            7














            You 'can' do it ... but it's not very wise ... this is about as daring as I'll try ... as far as full RegEx support your much better off using perl or the like.



            UPDATE db.tbl
            SET column =
            CASE
            WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'
            THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
            END
            WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'





            share|improve this answer





















            • 1





              No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

              – Ryan Shillington
              Oct 3 '12 at 17:14






            • 1





              @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

              – Eddie B
              Oct 3 '12 at 17:21






            • 1





              Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

              – Eddie B
              Oct 10 '12 at 23:33








            • 2





              @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

              – Eddie B
              Apr 29 '13 at 18:16






            • 2





              I guess there's a difference between "not wise" and "incorrect".

              – jmilloy
              Sep 26 '13 at 14:32
















            7














            You 'can' do it ... but it's not very wise ... this is about as daring as I'll try ... as far as full RegEx support your much better off using perl or the like.



            UPDATE db.tbl
            SET column =
            CASE
            WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'
            THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
            END
            WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'





            share|improve this answer





















            • 1





              No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

              – Ryan Shillington
              Oct 3 '12 at 17:14






            • 1





              @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

              – Eddie B
              Oct 3 '12 at 17:21






            • 1





              Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

              – Eddie B
              Oct 10 '12 at 23:33








            • 2





              @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

              – Eddie B
              Apr 29 '13 at 18:16






            • 2





              I guess there's a difference between "not wise" and "incorrect".

              – jmilloy
              Sep 26 '13 at 14:32














            7












            7








            7







            You 'can' do it ... but it's not very wise ... this is about as daring as I'll try ... as far as full RegEx support your much better off using perl or the like.



            UPDATE db.tbl
            SET column =
            CASE
            WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'
            THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
            END
            WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'





            share|improve this answer















            You 'can' do it ... but it's not very wise ... this is about as daring as I'll try ... as far as full RegEx support your much better off using perl or the like.



            UPDATE db.tbl
            SET column =
            CASE
            WHEN column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'
            THEN REPLACE(column,'WORD_TO_REPLACE','REPLACEMENT')
            END
            WHERE column REGEXP '[[:<:]]WORD_TO_REPLACE[[:>:]]'






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 28 '12 at 3:15

























            answered Sep 28 '12 at 3:09









            Eddie BEddie B

            3,98012835




            3,98012835








            • 1





              No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

              – Ryan Shillington
              Oct 3 '12 at 17:14






            • 1





              @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

              – Eddie B
              Oct 3 '12 at 17:21






            • 1





              Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

              – Eddie B
              Oct 10 '12 at 23:33








            • 2





              @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

              – Eddie B
              Apr 29 '13 at 18:16






            • 2





              I guess there's a difference between "not wise" and "incorrect".

              – jmilloy
              Sep 26 '13 at 14:32














            • 1





              No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

              – Ryan Shillington
              Oct 3 '12 at 17:14






            • 1





              @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

              – Eddie B
              Oct 3 '12 at 17:21






            • 1





              Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

              – Eddie B
              Oct 10 '12 at 23:33








            • 2





              @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

              – Eddie B
              Apr 29 '13 at 18:16






            • 2





              I guess there's a difference between "not wise" and "incorrect".

              – jmilloy
              Sep 26 '13 at 14:32








            1




            1





            No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

            – Ryan Shillington
            Oct 3 '12 at 17:14





            No, that won't work. Imagine your column contains 'asdfWORD_TO_REPLACE WORD_TO_REPLACE". Your method would result in 'asdfREPLACEMENT REPLACEMENT" where the correct answer would be "asdfWORD_TO_REPLACE REPLACEMENT".

            – Ryan Shillington
            Oct 3 '12 at 17:14




            1




            1





            @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

            – Eddie B
            Oct 3 '12 at 17:21





            @Ryan ... that's exactly why I stated that it wasn't very wise ... in the use case you provide this would most definitely fail. In short it's a bad idea to use 'regex-like' structure. Even worse ... if you drop the where clause all your values will be NULL ...

            – Eddie B
            Oct 3 '12 at 17:21




            1




            1





            Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

            – Eddie B
            Oct 10 '12 at 23:33







            Actually Ryan in this case you're incorrect as the markers will only find matches for the zero-length word 'boundaries' so only words with boundaries before and after the word would match ... It's still a bad idea though ...

            – Eddie B
            Oct 10 '12 at 23:33






            2




            2





            @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

            – Eddie B
            Apr 29 '13 at 18:16





            @RyanShillington "Sigh ... It would have wiser to simply not answer this one :-)"

            – Eddie B
            Apr 29 '13 at 18:16




            2




            2





            I guess there's a difference between "not wise" and "incorrect".

            – jmilloy
            Sep 26 '13 at 14:32





            I guess there's a difference between "not wise" and "incorrect".

            – jmilloy
            Sep 26 '13 at 14:32











            4














            We can use IF condition in SELECT query as below:



            Suppose that for anything with "ABC","ABC1","ABC2","ABC3",..., we want to replace with "ABC" then using REGEXP and IF() condition in the SELECT query, we can achieve this.



            Syntax:



            SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
            FROM table1
            WHERE column_name LIKE 'ABC%';


            Example:



            SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');





            share|improve this answer


























            • Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

              – Piskvor
              Dec 1 '14 at 8:38
















            4














            We can use IF condition in SELECT query as below:



            Suppose that for anything with "ABC","ABC1","ABC2","ABC3",..., we want to replace with "ABC" then using REGEXP and IF() condition in the SELECT query, we can achieve this.



            Syntax:



            SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
            FROM table1
            WHERE column_name LIKE 'ABC%';


            Example:



            SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');





            share|improve this answer


























            • Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

              – Piskvor
              Dec 1 '14 at 8:38














            4












            4








            4







            We can use IF condition in SELECT query as below:



            Suppose that for anything with "ABC","ABC1","ABC2","ABC3",..., we want to replace with "ABC" then using REGEXP and IF() condition in the SELECT query, we can achieve this.



            Syntax:



            SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
            FROM table1
            WHERE column_name LIKE 'ABC%';


            Example:



            SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');





            share|improve this answer















            We can use IF condition in SELECT query as below:



            Suppose that for anything with "ABC","ABC1","ABC2","ABC3",..., we want to replace with "ABC" then using REGEXP and IF() condition in the SELECT query, we can achieve this.



            Syntax:



            SELECT IF(column_name REGEXP 'ABC[0-9]$','ABC',column_name)
            FROM table1
            WHERE column_name LIKE 'ABC%';


            Example:



            SELECT IF('ABC1' REGEXP 'ABC[0-9]$','ABC','ABC1');






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Dec 1 '14 at 8:37









            Piskvor

            71.9k41153208




            71.9k41153208










            answered Dec 1 '14 at 6:37









            user3796869user3796869

            1118




            1118













            • Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

              – Piskvor
              Dec 1 '14 at 8:38



















            • Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

              – Piskvor
              Dec 1 '14 at 8:38

















            Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

            – Piskvor
            Dec 1 '14 at 8:38





            Hello, thank you for the suggestion. I have been trying something similar, but the performance on my data sets has been unsatisfactory. For smallish sets, this may be viable.

            – Piskvor
            Dec 1 '14 at 8:38





            protected by Samuel Liew Oct 5 '15 at 9:21



            Thank you for your interest in this question.
            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



            Would you like to answer one of these unanswered questions instead?



            Popular posts from this blog

            Berounka

            Fiat S.p.A.

            Type 'String' is not a subtype of type 'int' of 'index'