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

标签 mysql regex text-manipulation

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

SELECT `id`, `originaltext` FROM `source` WHERE `originaltext` regexp '[0-9][0-9]'

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

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

理想情况下,如果我可以添加应该大于 20 的其他标准,那就太好了,但我也可以单独执行。

最佳答案

如果您想在您的数据库中拥有更多的正则表达式功能,您可以考虑使用 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

关于mysql - 如何从 MySQL 中的文本字段中提取两个连续的数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5361457/

相关文章:

mysql - SQL 查询语法错误,使用 INNER JOIN 的 UPDATE 语句

regex - 在重复结构中使用正则表达式反向引用 ({N})

mysql - 如何使用 sequelize 和 Graphql 正确解析查询 MySql

mysql - 循环 mysql_real_connect 或者什么

php - 将多个表行移动到另一个表而不刷新页面

regex - 从 OCR 图像文件中提取文本

sql - Oracle - regexp_replace 用逗号分隔的字符串中的空值

PHP 修复错误文本

php - 对 UTF8 文本使用 str_word_count

regex - 如何从 Python 文件中提取两个子字符串之间的文本