1

我在 MySQL 数据库中有一个字段,其中包含所购产品的项目描述。其中一些是简单的英语描述,另一些是零件编号,还有一些仍然是零件编号,后跟描述。我已经使用 replace() 从字符串中删除了所有空格和破折号。

数据如下所示:

1938420985390asdfih
1234812934810dflkasd
asdfasldkjfaasdfjasd
asd;flkjaklsdf
adfsdf1234073927357sdapjfas
1/4sdikhsd 

我想返回:

1938420985390
1234812934810
(null)
(null)
1234073927357
(null)

我真正需要的是编写一个 SQL 来返回 13 位数的零件编号,而不是额外的字母/字符。我希望它也返回实际数字,而不是匹配/不匹配的 1 或 0。

我尝试使用 REGEXP 函数(有人建议regexp ('\d{13}')regexp ('\p{13}')但这些不起作用。[这些返回 0 或 1,而不是匹配的字符串部分。] 有什么建议吗?

谢谢!

4

5 回答 5

1

这是 MySQL 中的一项重要任务,没有用于返回正则表达式匹配的内置函数。但是因为您正在寻找正好 13 位数字,所以您可以这样做(显然将其扩展到您需要检查的位置数......

-- setup test
CREATE TABLE t (foo VARCHAR(30));
INSERT INTO t VALUES 
('1938420985390asdfih')
,('1234812934810dflkasd')
,('asdfasldkjfaasdfjasd')
,('asd;flkjaklsdf')
,('adfsdf1234073927357sdapjfas')
,('1/4sdikhsd')


SELECT CASE
       WHEN SUBSTR(foo,1,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,1,13)
       WHEN SUBSTR(foo,2,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,2,13)
       WHEN SUBSTR(foo,3,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,3,13)
       WHEN SUBSTR(foo,4,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,4,13)
       WHEN SUBSTR(foo,5,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,5,13)
       WHEN SUBSTR(foo,6,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,6,13)
       WHEN SUBSTR(foo,7,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,7,13)
       WHEN SUBSTR(foo,8,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,8,13)
       WHEN SUBSTR(foo,9,13) REGEXP '^[0-9]{13}$' THEN SUBSTR(foo,9,13)
       END AS digits
  FROM t

-------------------
1938420985390
1234812934810
(NULL)
(NULL)
1234073927357
(NULL) 

不,它不漂亮。但是您应该能够扩展它以有效地“扫描”合理长度的字符串。

注意:正则表达式检查整个 13 个字符的子字符串是否正好由 13 个字符组成,每个字符都是一个十进制数字(0 到 9)。

于 2012-08-23T14:58:20.223 回答
0

如此处所述,MySQL 可能不支持取回匹配的值 - MySQL 正则表达式与 REGEXP 运算符。但是,如链接中所述,您可以像这样使用第 3 方库:UDF Repository for MySQL,它允许您使用PREG_CAPTURE.

有关更多信息,这个StackOverflow 链接似乎已经处理了这个问题。

于 2012-08-23T14:52:15.303 回答
0

如果每个条目仅包含一个数字代码实例,则此实例有效:

SELECT CASE WHEN LENGTH(firstNumber(foo)) > 3 THEN firstNumber(foo) ELSE '' END AS result
FROM t

有两点值得一提:

  1. 数字的长度必须至少有一定的长度,比如 3 位,这样我们就可以避免第 6 行 '1/4sdikhsd' 中的 1 之类的结果;
  2. 函数firstNumber被修改为返回文本,但实际上是相同的:

    DELIMITER //
    CREATE FUNCTION firstNumber(s TEXT)
        RETURNS TEXT
        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
            SET ind = len + 1;
        END IF;
        SET ind = ind + 1;
    END WHILE;
    
    IF token = '' THEN
        RETURN '';
    END IF;
    
    RETURN token;
    
    END //    DELIMITER ;
    
于 2018-04-03T14:01:35.100 回答
0

您正在寻找的功能是REGEXP_SUBSTR()

SELECT REGEXP_SUBSTR(`dirty_value`,'[0-9]+') AS `clean_value` FROM `the_table`;

注意:我对其进行了测试并且可以工作;我正在使用 MySQL Server v8.0(不确定它在以前的版本中是否有效)。

祝你好运!

于 2019-06-01T20:40:59.040 回答
-1

而不是mysql你可以grep在linux中使用命令轻松完成

grep [0-9] foo.txt

然后创建表并将其加载到mysql中。

于 2016-06-15T17:12:59.460 回答