在MySQL中提取子字符串

时间:2014-09-26 02:03:26

标签: mysql sql regex string

假设我有一串带有引号字符串的随机字符,如下所示:

  

一个:15:I:0:3: “FOO” 我:1秒:3: “BAR” 我:2S:3: “BAZ” 我:3秒:3: “ALPHA100” 我:4S:3:” ALPHA500 “我:5秒:3:” BRAVO250" 我:6S:3

我想匹配引用的字符串,里面总是包含三个大写字母或五个大写字母后跟三个数字。在JavaScript中,我可以这样做:

" the string ".match(/"([A-Z]{3}|[A-Z]{5}\d{3})"/g);

我已经查看了MySQL的REGEXP运算符,但这似乎只适用于条件子句。

理想情况下,我想选择所有字符串,修剪引号,并执行GROUP_CONCAT以获取一行的最终结果集,如下所示:

"FOO,BAR,BAZ,ALPHA100,ALPHA500,BRAVO250"

理想情况下,我想在数据库级别执行此操作,以避免下载所有字符串并通过我的单行JavaScript程序运行它们。

1 个答案:

答案 0 :(得分:0)

我将展示一个基于字符串拆分的功能,如SQL split values to multiple rows所示,可以像

一样使用
SELECT get_the_parts(theString) FROM example;

此功能的工作原理如下: - 使用双引号作为分隔符将字符串拆分为包含部分的表 - 仅选择与3个大写字母或5个大写字母后跟3个数字匹配的部分 - 使用逗号作为分隔符连接选定的部分

DELIMITER //
CREATE FUNCTION get_the_parts(myString VARCHAR(2000)) RETURNS VARCHAR(2000)
BEGIN
  DECLARE result VARCHAR(2000);

  SELECT
    GROUP_CONCAT(t.value) INTO result
    FROM (
      SELECT
        SUBSTRING_INDEX(SUBSTRING_INDEX(e.col, '"', n.n), '"', -1) value
      FROM ( SELECT myString AS col ) e
      CROSS JOIN (
        -- creates a numbers table with the values from 1 to 1,000 on the fly
        SELECT 
            1 + a.N + b.N * 10 + c.N * 100 AS n
        FROM
            (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
            ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
            ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) c
        ORDER BY n    
      ) n
      WHERE
        n.n <= 1 + LENGTH(myString) - LENGTH(REPLACE(myString, '"', '')) 
    ) t
    WHERE 
        t.value REGEXP '^([A-Z]{3}|[A-Z]{5}[0-9]{3})$';

    return result;
END //
DELIMITER ;

解释

创建数字表

带有UNION ALL的最里面的子选择动态创建一个数字表,其数字从1到1000.此子选项很容易被数据库中的数字表替换。

拆分字符串

通过嵌套调用SUBSTRING_INDEX,我们剪切了分隔符之间的第n个子字符串。我们使用双引号作为分隔符:

SUBSTRING_INDEX(SUBSTRING_INDEX(e.col, '"', n.n), '"', -1)

表达式

1 + LENGTH(myString) - LENGTH(REPLACE(myString, '"', ''))

给出了部件的数量,因为它比分隔符的出现多出一次。

选择需要的部分

我们使用正则表达式

'^([A-Z]{3}|[A-Z]{5}[0-9]{3})$'

因为我们的部分必须与已知的正则表达式从开头^完全匹配,直到结束$而没有更多内容。

<强>级联

最后,我们使用GROUP_CONCATE和默认分隔符comma来获得所需的结果。

说明

我已经建立了 Demo 您可以轻松修改此功能以满足您的需求 你真的喜欢这个吗?我建议使用你的单行javascript。这种形式的文本处理并不是关系数据库最好的。