【问题标题】:Mysql: using regexp matches as fields?Mysql:使用正则表达式匹配作为字段?
【发布时间】:2013-06-17 12:26:21
【问题描述】:

我阅读了mysql documentation about regexp,但看起来正则表达式只能用作WHERE 过滤器以匹配SELECT 查询中的行。

我想知道是否可以将正则表达式的匹配项提取为列,例如,如果在我的表中我有一个 SKU 文本字段:

+----------------+--------------+---------------+
|sku             | product_name | [other fields]|
+----------------+--------------+---------------+
|ART-2830--107-70| Foo          |               |
|ART-2832--115-6 | Bar          |               |
+----------------+--------------+---------------+

最好触发一个匹配正则表达式 (ART-)([0-9]+)(--)([0-9]+)(-)([0-9]+) 的选择查询,它给我作为输出:

+------+------------+-------+----------+
| type | collection | model | material |
+------+------------+-------+----------+
| ART  | 2830       | 107   | 70       |
| ART  | 2832       | 115   | 6        |
+------+------------+-------+----------+

请注意,type, collection, model and material 列不存在于我的表中,只是上面正则表达式的匹配项。

这可能吗?

p.s:我知道规范化该表为我需要的每个 property 添加一列是一个好主意,但这是我必须使用的结构,我无法在瞬间。

编辑以防万一有人需要,我看到了PostgreSql offer this function

【问题讨论】:

    标签: mysql sql regex database


    【解决方案1】:

    一般来说,答案是“不”——至少在没有大量蛮力编码的情况下是这样。但是,你很幸运,因为你可以在 MySQL 中“轻松”地做你想做的事:

    select substring_index(sku, '-', 1) as type,
           reverse(substring_index(reverse(substring_index(sku, '-', 2)), '-', 1)) as collection,
           reverse(substring_index(reverse(substring_index(sku, '-', 4)), '-', 1)) as model,
           reverse(substring_index(reverse(substring_index(sku, '-', 5)), '-', 1)) as material
    from skus
    

    好吧,也许不是最明显的函数集合。但这是它对模型的作用:

    开头:ART-2830--107-70

    substring_index(sku, '-', 4) --> ART-2830--107
    

    reverse():

    701--0381-TRA

    substring_index( . . . 1)

    701
    

    还有最后的reverse()

    107
    

    【讨论】:

    • 很遗憾这是唯一的方法。在这一点上,使用正则表达式从数据库中获取数据以匹配行然后处理结果服务器端要好得多。如果我只能创建另一个表来规范化数据..
    【解决方案2】:

    在选择语句中使用正则表达式实际上取决于 sql 语言。对于 MySql,您可以在手册中阅读更多内容。

    手册的这一部分讨论使用正则表达式选择语句:http://dev.mysql.com/doc/refman/5.7/en/regexp.html。该手册页还包含以下链接,指向如何将正则表达式语句用于 where 语句的示例。

    http://dev.mysql.com/doc/refman/5.7/en/pattern-matching.html

    这个例子也在手册中。

    To find names containing a “w”, use this query:
    
    mysql> SELECT * FROM pet WHERE name REGEXP 'w';
    +----------+-------+---------+------+------------+------------+
    | name     | owner | species | sex  | birth      | death      |
    +----------+-------+---------+------+------------+------------+
    | Claws    | Gwen  | cat     | m    | 1994-03-17 | NULL       |
    | Bowser   | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
    | Whistler | Gwen  | bird    | NULL | 1997-12-09 | NULL       |
    +----------+-------+---------+------+------------+------------+
    

    能否根据正则表达式捕获组返回数据?

    没有。 where 语句过滤 SQL 引擎返回的数据。您需要为要返回的每一列数据建立一个条目。正如 Gordon Linoff 的回答一样,每一列都可以由 SQL 处理,以手动从给定列中提取数据。但这种解决方案远非使用正则表达式描述 sql select 语句的理想。

    您打算使用正则表达式捕获组来提取数据,那么这需要在您收到数据后完成。

    【讨论】:

    • 我的问题的第一行告诉 我阅读了有关 regexp 的 mysql 文档,但看起来 regexp 可以用作 WHERE 过滤器来匹配 SELECT 查询中的行。 你跳过了吗那部分?
    • 更新了答案以准确显示 MySql 手册中关于如何使用正则表达式作为 WHERE 过滤器来匹配 SELECT 查询中的行的位置。
    • 对不起,伙计,我不想显得粗鲁,但是如果您阅读了我的问题,您会发现您的答案不相关..我没有问 如何在 mysql 中使用正则表达式 i> 但是如何将正则表达式的匹配项用作列 我想这是一个误解;)让我更新我的问题以澄清这一点
    • 更新了答案以涵盖确切的问题:如何使用正则表达式捕获组来定义从 select 语句返回的数据列。
    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2014-11-12
    • 1970-01-01
    • 2013-09-05
    相关资源
    最近更新 更多