mysql - 在 MySQL 中提取子字符串

标签 mysql sql regex string

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

a:15:i:0s:3:"FOO"i:1s:3:"BAR"i:2s:3:"BAZ"i:3s:3:"ALPHA100"i:4s:3:"ALPHA500"i:5s:3:"BRAVO250"i:6s:3

我想匹配其中始终包含三个大写字母或五个大写字母后跟三个数字的带引号的字符串。在 JavaScript 中我可以这样做:

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

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

理想情况下,我想选择所有字符串,去掉引号,然后执行 GROUP_CONCAT 以返回一行的最终结果集,如下所示:

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

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

最佳答案

我将展示一个基于字符串拆分的函数,如 SQL split values to multiple rows 中所示。像这样使用

SELECT get_the_parts(theString) FROM example;

这个函数是这样工作的: - 使用双引号作为分隔符将字符串拆分成一个表 - 仅选择与 3 个大写字母或 5 个大写字母后跟三个数字完全匹配的部分 - 使用逗号作为分隔符连接所选部分

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 来获得所需的结果。

备注

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

关于mysql - 在 MySQL 中提取子字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26050924/

相关文章:

mysql - 获取 mySql 中不同计数的计数

javascript - 用于捕获 float 范围 (3.0 – 5.5) 的正则表达式

PHP 和 MySQL 最佳实践——为管理员和用户创建不同的 View

PHP/MySQL - "BEGIN...COMMIT"不工作

mysql - 运行personal.xlsb宏而不打开excel

c# - 中间有一个特殊字符的字母数字字符的正则表达式

ruby - 如果存在,则从字符串中删除前导引号和尾随引号

mysql - 获取 MySQL 多行插入中的插入 ID

mysql - 使用更新触发器将数据从一个表移动到另一个表

sql - 如何在 SQLite 中添加默认值?