如何从MySQL中的文本字段中提取两个连续数字?

Ste*_*eve 27 regex mysql text-manipulation

我有一个MySQL数据库,我有一个查询:

SELECT `id`, `originaltext` FROM `source` WHERE `originaltext` regexp '[0-9][0-9]'
Run Code Online (Sandbox Code Playgroud)

这将检测所有包含2位数字的原始文本.

我需要MySQL将这些数字作为字段返回,所以我可以进一步操作它们.

理想情况下,如果我可以添加额外的标准,应该> 20将是伟大的,但我也可以单独做.

Pen*_*m10 12

如果您想在数据库中使用更多正则表达式,可以考虑使用LIB_MYSQLUDF_PREG.这是一个导入PCRE库的MySQL用户函数的开源库.LIB_MYSQLUDF_PREG仅以源代码形式提供.要使用它,您需要能够编译它并将其安装到MySQL服务器中.安装此库不会以任何方式更改MySQL的内置正则表达式支持.它只是提供以下附加功能:

PREG_CAPTURE从字符串中提取正则表达式匹配.PREG_POSITION返回正则表达式与字符串匹配的位置.PREG_REPLACE对字符串执行搜索和替换.PREG_RLIKE测试正则表达式是否匹配字符串.

所有这些函数都将正则表达式作为其第一个参数.此正则表达式必须格式化为Perl正则表达式运算符.例如,为了测试正则表达式是否与主题不敏感匹配,您将使用MySQL代码PREG_RLIKE('/ regex/i',subject).这类似于PHP的preg函数,它还需要PHP字符串中正则表达式的额外//分隔符.

如果你想要更简单的东西,你可以改变这个功能,以更好地满足你的需求.

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
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 9

MySQL中没有任何语法可以使用正则表达式提取文本.您可以使用REGEXP来标识包含两个连续数字的行,但要提取它们,您必须使用普通的字符串操作函数,在这种情况下这非常困难.

备择方案:

  • 从数据库中选择整个值,然后在客户端上使用正则表达式.
  • 使用对SQL标准有更好支持的其他数据库(我知道可能不是一个选项).然后你可以用这个:SUBSTRING(originaltext from '%#[0-9]{2}#%' for '#').