从MySQL中的文本字段中选择仅数字模式

时间:2015-06-08 14:42:25

标签: mysql sql regex

我的表中有一列包含一些大型日志记录数据的文本记录。这些字段将具有以“3”开头的9位数字(0-9)。

我只想选择 仅显示此字段中的模式,而不是整个字段。为了使事情变得复杂,这种模式可以在字段中不止一次

我认为REGEX我需要的是3{8}[0-9]吗?

是否有MySQL方式才能这样做?我宁愿不用编写php脚本来提取这些数据。

编辑:看起来这对REGEX来说是不可能的 - 可以用任何其他MySQL字符串函数来完成吗?

3 个答案:

答案 0 :(得分:2)

在处理非规范化数据时,我认为MySQL或SQL通常不是文本挖掘的正确工具。

只是

$ mysql_dump mydb mytable > dump.sql

将您的数据存入文件,然后使用

搜索您的模式
$ grep -o '3[0-9]\{8\}' dump.sql > numbers.txt
  • -o告诉grep只显示匹配的数据。
  • 3[0-9]是匹配3any number between 0-9
  • 的模式
  • \{8\}{8}的转义形式,告诉grep前一个模式应该恰好匹配8次

讨论中的最终命令,它还要求9位数后的非数字值:

$ grep -Po '3[0-9]{8}(?=[^0-9])' dump.sql > numbers.txt
  • 使用perl regexp,因此不需要转义
  • (?= ...)是匹配的前瞻,但未包含在结果中

答案 1 :(得分:0)

  

这些字段将包含以" 3"开头的9位数字(0-9)。

这里有3个案例来展示正则表达式并且它符合该规范:

+----------------------------------+----------------------------------+---------------------------------------+
| '123456789' REGEXP '^3[0-9]{8}$' | '323456789' REGEXP '^3[0-9]{8}$' | 'junk-323456789' REGEXP '^3[0-9]{8}$' |
+----------------------------------+----------------------------------+---------------------------------------+
|                                0 |                                1 |                                     0 |
+----------------------------------+----------------------------------+---------------------------------------+

答案 2 :(得分:0)

正如其他人所提到的,SQL并不特别适合在文本内部进行探索。但你可以做一些存储功能。这是一个从文本值中获取第一个正整数的方法。如果你没有在你想要的模式之前有其他数字,那可能就足够了;或者你可以很容易地修改它以获得你想要的更精确的模式(例如,测试它找到的每个数字,如果它不是你想要的形式,丢弃它并继续寻找而不是退出循环) :

DROP FUNCTION IF EXISTS firstNumber;

DELIMITER //
CREATE FUNCTION firstNumber(s TEXT)
    RETURNS INTEGER
    COMMENT 'Returns the first integer found in a string'
    DETERMINISTIC
    BEGIN

    DECLARE token TEXT DEFAULT '';
    DECLARE len INTEGER DEFAULT 0;
    DECLARE ind INTEGER DEFAULT 0;
    DECLARE thisChar CHAR(1) DEFAULT ' ';

    SET len = CHAR_LENGTH(s);
    SET ind = 1;
    WHILE ind <= len DO
        SET thisChar = SUBSTRING(s, ind, 1);
        IF (ORD(thisChar) >= 48 AND ORD(thisChar) <= 57) THEN
            SET token = CONCAT(token, thisChar);
        ELSEIF token <> '' THEN
            -- Could add extra pattern check here
            SET ind = len + 1;
        END IF;
        SET ind = ind + 1;
    END WHILE;

    IF token = '' THEN
        RETURN 0;
    END IF;

    RETURN token;

    END //
DELIMITER ;