71 votes

MySQL: comment supprimer tous les caractères non alphanumériques d'une chaîne?

Je travaille sur une routine qui compare les chaînes, mais pour une meilleure efficacité, je dois supprimer tous les caractères qui ne sont ni des lettres ni des chiffres.

J'utilise plusieurs fonctions REPLACE maintenant, mais peut-être y a-t-il une solution plus rapide et plus agréable?

102voto

Ryan Shillington Points 558

Aucune de ces réponses n'a fonctionné pour moi. Je devais créer ma propre fonction appelée alphanum qui supprimait les caractères pour moi:

 DROP FUNCTION IF EXISTS alphanum; 
DELIMITER | 
CREATE FUNCTION alphanum( str CHAR(32) ) RETURNS CHAR(16) 
BEGIN 
  DECLARE i, len SMALLINT DEFAULT 1; 
  DECLARE ret CHAR(32) DEFAULT ''; 
  DECLARE c CHAR(1); 
  SET len = CHAR_LENGTH( str ); 
  REPEAT 
    BEGIN 
      SET c = MID( str, i, 1 ); 
      IF c REGEXP '[[:alnum:]]' THEN 
        SET ret=CONCAT(ret,c); 
      END IF; 
      SET i = i + 1; 
    END; 
  UNTIL i > len END REPEAT; 
  RETURN ret; 
END | 
DELIMITER ; 
 

Maintenant je peux faire:

 select 'This works finally!', alphanum('This works finally!');
 

et je reçois:

 +---------------------+---------------------------------+
| This works finally! | alphanum('This works finally!') |
+---------------------+---------------------------------+
| This works finally! | Thisworksfinally                |
+---------------------+---------------------------------+
1 row in set (0.00 sec)
 

Hourra!

22voto

Kevin Burton Points 5460

Du point de vue de la performance (et en supposant que vous lisiez plus que vous n’écrivez)

Je pense que le meilleur moyen serait de pré-calculer et de stocker une version dépouillée de la colonne, de cette façon, vous transformerez moins.

Vous pouvez ensuite mettre un index sur la nouvelle colonne et demander à la base de données de faire le travail à votre place.

15voto

Johan Points 34755
 SELECT teststring REGEXP '[[:alnum:]]+';

SELECT * FROM testtable WHERE test REGEXP '[[:alnum:]]+'; 
 

Voir: http://dev.mysql.com/doc/refman/5.1/en/regexp.html
Faites défiler jusqu'à la section qui dit: [:character_class:]

Si vous voulez manipuler des chaînes, le moyen le plus rapide consiste à utiliser un str_udf, voir:
http://www.mysqludf.org/lib_mysqludf_str/index.php

6voto

vdd Points 105

Le moyen le plus rapide, j'ai pu trouver (et l'utilisation ) est avec la fonction convert().

de Doc. La fonction CONVERT() avec l'AIDE est utilisée pour convertir des données entre les différents jeux de caractères.

Exemple:

convert(string USING ascii)

Dans votre cas, le bon jeu de caractères seront définis auto

NOTE de Doc. L' AIDE sous forme de CONVERT() de 4.1.0.

4voto

J'ai écrit cet UDF, mais je coupe les caractères spéciaux juste au début et convertis en ase inférieur. Mais vous pouvez mettre à jour cette fonction

 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//

DROP FUNCTION IF EXISTS LFILTER//

CREATE FUNCTION LFILTER ( title VARCHAR(250) )
RETURNS VARCHAR(250) DETERMINISTIC
BEGIN
    WHILE (1=1) DO
        IF(  ASCII(title) BETWEEN ASCII('a') AND ASCII('z')
            OR ASCII(title) BETWEEN ASCII('A') AND ASCII('Z')
            OR ASCII(title) BETWEEN ASCII('0') AND ASCII('9')
        ) THEN
            SET title = LOWER( title );
            SET title = REPLACE(
                REPLACE(
                    REPLACE(
                        title,
                        CHAR(10), ' '
                    ),
                    CHAR(13), ' '
                ) ,
                CHAR(9), ' '
            );
            SET title = DELETE_DOUBLE_SPACES( title );
            RETURN title;
        ELSE
            SET title = SUBSTRING( title, 2 );          
        END IF;
    END WHILE;
END//
DELIMITER ;

SELECT LFILTER(' !@#$%^&*()_+1a    b');
 

Aussi, vous pouvez utiliser des expressions régulières, mais vous devrez installer l'extension MySql

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X