Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment extraire deux chiffres consécutifs d'un champ texte dans MySQL ?

Si vous voulez plus de puissance d'expression régulière dans votre base de données, vous pouvez envisager d'utiliser LIB_MYSQLUDF_PREG . Il s'agit d'une bibliothèque open source de fonctions utilisateur MySQL qui importe la bibliothèque PCRE. LIB_MYSQLUDF_PREG est livré uniquement sous forme de code source. Pour l'utiliser, vous devez être capable de le compiler et de l'installer sur votre serveur MySQL. L'installation de cette bibliothèque ne change en rien la prise en charge intégrée des regex de MySQL. Il met simplement à disposition les fonctions supplémentaires suivantes :

PREG_CAPTURE extrait une correspondance de regex d'une chaîne. PREG_POSITION renvoie la position à laquelle une expression régulière correspond à une chaîne. PREG_REPLACE effectue une recherche et remplacement sur une chaîne. PREG_RLIKE teste si une expression régulière correspond à une chaîne.

Toutes ces fonctions prennent une expression régulière comme premier paramètre. Cette expression régulière doit être formatée comme un opérateur d'expression régulière Perl. Par exemple. pour tester si regex correspond au sujet de manière insensible, vous utiliseriez le code MySQL PREG_RLIKE('/regex/i', sujet). Ceci est similaire aux fonctions preg de PHP, qui nécessitent également les // délimiteurs supplémentaires pour les expressions régulières à l'intérieur de la chaîne PHP.

Si vous voulez quelque chose de plus simple, vous pouvez modifier cette fonction pour mieux répondre à vos besoins.

CREATE FUNCTION REGEXP_EXTRACT(string TEXT, exp TEXT)
-- Extract the first longest string that matches the regular expression
-- If the string is 'ABCD', check all strings and see what matches: 'ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D'
-- It's not smart enough to handle things like (A)|(BCD) correctly in that it will return the whole string, not just the matching token.

RETURNS TEXT
DETERMINISTIC
BEGIN
  DECLARE s INT DEFAULT 1;
  DECLARE e INT;
  DECLARE adjustStart TINYINT DEFAULT 1;
  DECLARE adjustEnd TINYINT DEFAULT 1;

  -- Because REGEXP matches anywhere in the string, and we only want the part that matches, adjust the expression to add '^' and '$'
  -- Of course, if those are already there, don't add them, but change the method of extraction accordingly.

  IF LEFT(exp, 1) = '^' THEN 
    SET adjustStart = 0;
  ELSE
    SET exp = CONCAT('^', exp);
  END IF;

  IF RIGHT(exp, 1) = '$' THEN
    SET adjustEnd = 0;
  ELSE
    SET exp = CONCAT(exp, '$');
  END IF;

  -- Loop through the string, moving the end pointer back towards the start pointer, then advance the start pointer and repeat
  -- Bail out of the loops early if the original expression started with '^' or ended with '$', since that means the pointers can't move
  WHILE (s <= LENGTH(string)) DO
    SET e = LENGTH(string);
    WHILE (e >= s) DO
      IF SUBSTRING(string, s, e) REGEXP exp THEN
        RETURN SUBSTRING(string, s, e);
      END IF;
      IF adjustEnd THEN
        SET e = e - 1;
      ELSE
        SET e = s - 1; -- ugh, such a hack to end it early
      END IF;
    END WHILE;
    IF adjustStart THEN
      SET s = s + 1;
    ELSE
      SET s = LENGTH(string) + 1; -- ugh, such a hack to end it early
    END IF;
  END WHILE;

  RETURN NULL;

END