How to do a regular expression replace in MySQL?
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
|
show 2 more comments
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
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 createdregexp_split
(function + procedure) ®exp_replace
, which are implemented withREGEXP
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
|
show 2 more comments
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
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
mysql regex mysql-udf
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 createdregexp_split
(function + procedure) ®exp_replace
, which are implemented withREGEXP
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
|
show 2 more comments
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 createdregexp_split
(function + procedure) ®exp_replace
, which are implemented withREGEXP
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
|
show 2 more comments
10 Answers
10
active
oldest
votes
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
add a comment |
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
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
|
show 3 more comments
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
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
|
show 2 more comments
My brute force method to get this to work was just:
- Dump the table -
mysqldump -u user -p database table > dump.sql
- 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. - 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.
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
|
show 2 more comments
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 ._,');
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 likeselect 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
|
show 1 more comment
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
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
add a comment |
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.
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
add a comment |
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
- 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). - 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). - 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. - 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?
1
Wow! Is perfect!
– OscarR
Aug 3 '18 at 11:47
add a comment |
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[[:>:]]'
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
|
show 3 more comments
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');
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
add a comment |
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
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
add a comment |
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
add a comment |
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
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
edited May 6 '18 at 5:06
answered Apr 19 '18 at 16:07
Lukasz SzozdaLukasz Szozda
79.1k1061105
79.1k1061105
add a comment |
add a comment |
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
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
|
show 3 more comments
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
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
|
show 3 more comments
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
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
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
|
show 3 more comments
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
|
show 3 more comments
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
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
|
show 2 more comments
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
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
|
show 2 more comments
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
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
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
|
show 2 more comments
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
|
show 2 more comments
My brute force method to get this to work was just:
- Dump the table -
mysqldump -u user -p database table > dump.sql
- 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. - 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.
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
|
show 2 more comments
My brute force method to get this to work was just:
- Dump the table -
mysqldump -u user -p database table > dump.sql
- 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. - 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.
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
|
show 2 more comments
My brute force method to get this to work was just:
- Dump the table -
mysqldump -u user -p database table > dump.sql
- 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. - 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.
My brute force method to get this to work was just:
- Dump the table -
mysqldump -u user -p database table > dump.sql
- 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. - 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.
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
|
show 2 more comments
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
|
show 2 more comments
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 ._,');
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 likeselect 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
|
show 1 more comment
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 ._,');
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 likeselect 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
|
show 1 more comment
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 ._,');
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 ._,');
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 likeselect 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
|
show 1 more comment
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 likeselect 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
|
show 1 more comment
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
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
add a comment |
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
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
add a comment |
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
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
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
add a comment |
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
add a comment |
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.
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
add a comment |
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.
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
add a comment |
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.
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.
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
add a comment |
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
add a comment |
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
- 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). - 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). - 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. - 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?
1
Wow! Is perfect!
– OscarR
Aug 3 '18 at 11:47
add a comment |
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
- 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). - 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). - 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. - 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?
1
Wow! Is perfect!
– OscarR
Aug 3 '18 at 11:47
add a comment |
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
- 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). - 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). - 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. - 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?
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
- 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). - 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). - 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. - 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?
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
add a comment |
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
add a comment |
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[[:>:]]'
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
|
show 3 more comments
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[[:>:]]'
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
|
show 3 more comments
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[[:>:]]'
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[[:>:]]'
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
|
show 3 more comments
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
|
show 3 more comments
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');
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
add a comment |
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');
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
add a comment |
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');
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');
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
add a comment |
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
add a comment |
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?
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) ®exp_replace
, which are implemented withREGEXP
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