【问题标题】:return numbers from the middle of a string with irregular format从不规则格式的字符串中间返回数字
【发布时间】:2012-08-19 02:56:31
【问题描述】:

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

数据如下所示:

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

我想回来:

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

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

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

谢谢!

【问题讨论】:

  • 你能定义这些正则表达式是如何不起作用的吗?有错误吗?结果返回时是否没有错误但为空?
  • @Corey:我很确定 OP 的意思是 REGEXP 表达式返回 1 或 0,而不是返回与模式匹配的值部分。 (MySQL 没有内置函数来返回匹配的字符串。)
  • @CoreyOgburn: spencer 是正确的......问题是它会返回 1 或 0。然后我可以使用唯一 ID 链接回列值,但想法是尝试将零件编号与另一个数据集匹配。我也可以对其他数据集执行此操作: concat("or item_desc like '%", part_number, "%'") 然后以这种方式运行大量查询,但这将花费很长时间......更不用说其他数据集并不详尽。

标签: mysql regex string substring


【解决方案1】:

你要找的函数是REGEXP_SUBSTR():

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

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

祝你好运!

【讨论】:

    【解决方案2】:

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

    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 ;
      

    【讨论】:

      【解决方案3】:

      您可以使用 linux 中的 grep 命令轻松完成,而不是 mysql

      grep [0-9] foo.txt
      

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

      【讨论】:

        【解决方案4】:

        这是 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)。

        【讨论】:

        • 这适用于 NULL 值、空字符串和少于 13 个字符的字符串。这基本上会在字符串中找到第一次出现的 13 个连续数字。您需要重复 WHEN 行,以包括从位置 10、11、12 等开始的检查。
        【解决方案5】:

        在 MySQL 中可能还不支持取回匹配的值,如此处所述 - MySQL Regular Expressions with The REGEXP Operator。但是,如链接中所述,您可以像这样使用第 3 方库:UDF Repository for MySQL,它允许您使用 PREG_CAPTURE 捕获匹配项。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-30
          • 1970-01-01
          • 2019-02-16
          • 2018-01-03
          • 2012-12-26
          • 2021-10-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多