I couldn\'t find this question for MySQL so here it is:
I need to trim all double or more spaces in a string to 1 single space.
For example: \"The  
Here's an old trick that does not require regular expressions or complicated functions.
You can use the replace function 3 times to handle any number of spaces, like so:
REPLACE('This is my long string',' ','<>')
becomes:
This<>is<><><><>my<><><>long<><><><>string
Then you replace all occurrences of '><' with an empty string '' by wrapping it in another replace:
REPLACE(
REPLACE('This is my long string',' ','<>'),
'><',''
)
This<>is<>my<>long<>string
Then finally one last replace converts the '<>' back to a single space
REPLACE(
REPLACE(
REPLACE('This is my long string',
' ','<>'),
'><',''),
'<>',' ')
This is my long string
This example was created in MYSQL (put a SELECT in front) but works in many languages.
Note that you only ever need the 3 replace functions to handle any number of characters to be replaced.
Follow my generic function made for MySQL 5.6. My intention was to use regular expression to identify the spaces, CR and LF, however, it is not supported by this version of mysql. So, I had to loop through the string looking for the characters.
CREATE DEFINER=`db_xpto`@`%` FUNCTION `trim_spaces_and_crlf_entire_string`(`StringSuja` text) RETURNS text CHARSET utf8 COLLATE utf8_unicode_ci
DETERMINISTIC
BEGIN
DECLARE StringLimpa TEXT;
DECLARE CaracterAtual, CaracterAnterior TEXT;
DECLARE Contador, TamanhoStringSuja INT;
SET StringLimpa = '';
SET CaracterAtual = '';
SET CaracterAnterior = '';
SET TamanhoStringSuja = LENGTH(StringSuja);
SET Contador = 1;
WHILE Contador <= TamanhoStringSuja DO
SET CaracterAtual = SUBSTRING(StringSuja, Contador, 1);
IF ( CaracterAtual = ' ' AND CaracterAnterior = ' ' ) OR CaracterAtual = '\n' OR CaracterAtual = '\r' THEN
/* DO NOTHING */
SET Contador = Contador;
/* TORNA OS ESPAÇOS DUPLICADOS, CR, LF VISUALIZÁVEIS NO RESULTADO (DEBUG)
IF ( CaracterAtual = ' ' ) THEN SET StringLimpa = CONCAT(StringLimpa, '*');END IF;
IF ( CaracterAtual = '\n' ) THEN SET StringLimpa = CONCAT(StringLimpa, '\\N');END IF;
IF ( CaracterAtual = '\r' ) THEN SET StringLimpa = CONCAT(StringLimpa, '\\R');END IF;
*/
ELSE
/* COPIA CARACTER ATUAL PARA A STRING A FIM DE RECONSTRUÍ-LA SEM OS ESPAÇOS DUPLICADOS */
SET StringLimpa = CONCAT(StringLimpa, CaracterAtual);
/*SET StringLimpa = CONCAT(StringLimpa, Contador, CaracterAtual);*/
SET CaracterAnterior = CaracterAtual;
END IF;
SET Contador = Contador + 1;
END WHILE;
RETURN StringLimpa;
END
If the string that you want to convert consists of only alphabets and multiple number of spaces [A-Za-z ]* then the following function will work. I found out a pattern when such strings are converted to hex. Based on that my solution follows. Not so elegant, but it doesn't require any procedures.
unhex(
replace(
replace(
replace(
replace(
replace(
replace(
hex(str)
,204,1014)
,205,1015)
,206,1016)
,207,1017)
,20,'')
,101,20)
)
DELIMITER //
DROP FUNCTION IF EXISTS DELETE_DOUBLE_SPACES//
CREATE FUNCTION DELETE_DOUBLE_SPACES ( title VARCHAR(250) )
RETURNS VARCHAR(250) DETERMINISTIC
BEGIN
DECLARE result VARCHAR(250);
SET result = REPLACE( title, ' ', ' ' );
WHILE (result <> title) DO
SET title = result;
SET result = REPLACE( title, ' ', ' ' );
END WHILE;
RETURN result;
END//
DELIMITER ;
SELECT DELETE_DOUBLE_SPACES('a b');
This is slightly general solution: from
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=56195&whichpage=1
create table t (s sysname)
insert into t select 'The Quick Brown Fox'
-- convert tabs to spaces
update t set s = replace(s, ' ',' ')
where charindex(' ', s) > 0
-- now do the work.
while 1=1
begin
update t
set s = substring(s, 1, charindex(' ', s, 1)-1) + ' ' + ltrim(substring(s,charindex(' ', s, 1), 8000))
where charindex(' ', s, 1) > 0
if @@rowcount = 0
break
end
select s
from t
The shortest and, surprisingly, the fastest solution:
CREATE FUNCTION clean_spaces(str VARCHAR(255)) RETURNS VARCHAR(255)
BEGIN
while instr(str, ' ') > 0 do
set str := replace(str, ' ', ' ');
end while;
return trim(str);
END