regexp模式以匹配不同类型的数据

时间:2018-04-15 10:19:59

标签: mysql regex

我有一个数据库(mysql)文本字段,包含不同的数据:

  • data1 - 用逗号分隔的个别数字:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 ... n(其中) n可以是任何正整数)

  • data2 - 用逗号分隔的文本:Lorem ipsum,dolor,sit amet,consectetur,adipiscing,elit,Ut et,sollicitudin,enim,vel,consectetur lacus

数据中不允许使用开头和结尾逗号,空格可以在逗号之前和/或以逗号开头,也可以在逗号之后。 2,3,4,5,6,7或Lorem ipsum,dolor,sit amet等等,这些空间现在可以在比赛中计算。

我需要在这些数据中以几种不同的方式进行搜索,因此我需要使用regexp模式进行搜索:

  • 模式A:匹配data1中的数字。如果我搜索1,那么我只需要1,而不是11,12等,

现在我有:[0-9]+(,[0-9]+)*

  • 模式B:匹配一系列数字:如果该字段包含(至少一个)两个给定数字之间的数字。
  • 模式C:匹配data2中由逗号分隔的完整字符串之一。喜欢:如果我搜索 ,我没有结果,但如果我为 坐下来 ,我得到了结果。

任何人都可以帮我这些吗?我用于模式A的是最好的方法,我如何匹配范围(模式B)和逗号分隔的字符串(模式C)?

2 个答案:

答案 0 :(得分:2)

您不需要正则表达式。
我将通过将MySQL数字生成器与嵌套的SUBSTRING_INDEX函数结合使用来向您展示一个技巧。
如果您需要支持更多CSV添加新的

   CROSS JOIN (
      SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) AS record_[number]

<强>查询

此查询将生成1到100之间的数字。 因此,最终查询最多可支持100个分隔值。

SELECT 
 (@number  := @number + 1) AS number
FROM (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_1
CROSS JOIN (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_2
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param

参见演示http://sqlfiddle.com/#!9/c314ca/5

现在我们将使用

从逗号分隔的字符串中提取值

<强>查询

将[position]替换为0 - 的数字 - ...要从逗号分隔的字符串中提取哪个值。

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15', ',', [position]), ',', -1) AS split;

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Lorem ipsum, dolor, sit amet, consectetur, adipiscing,elit, Ut et, sollicitudin, enim, vel, consectetur lacus ', ',', [position]), ',', -1) AS split;

参见演示http://sqlfiddle.com/#!9/c314ca/16

现在我们知道了将两个查询结合到工作解决方案的基础知识。
此查询将所有逗号分隔值转换为记录。
因为我不知道表结构,我认为它类似于

CREATE TABLE [name] (
    data1 TEXT
  , data2 TEXT
); 

<强>查询

SELECT
  DISTINCT 
      SUBSTRING_INDEX(SUBSTRING_INDEX(data1, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN
 Table1

UNION ALL 

SELECT
  DISTINCT 
      SUBSTRING_INDEX(SUBSTRING_INDEX(data2, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number2  := @number2 + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number2 := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN
 Table1

参见演示http://sqlfiddle.com/#!9/a19fc5/6

我把它分解成一小部分。

  

模式A:匹配data1中的数字。如果我搜索1,结果,   我只需要1,而不是11,12等,

因为我们现在有记录而不是逗号分隔值,所以我们可以简单地使用最后一个查询作为传递的表添加一个WHERE子句。

参见演示http://sqlfiddle.com/#!9/a19fc5/10

  

模式B:匹配一系列数字:如果该字段包含(at   两个给定数字之间的数字中的至少一个。

现在WHERE子句是一个简单的BETWEEN子句

参见演示http://sqlfiddle.com/#!9/a19fc5/11

  

模式C:匹配由逗号分隔的完整字符串之一   数据2。喜欢:如果我搜索坐,我没有结果,但如果我搜索   因为坐下来,我得到了结果。

现在你可以使用LIKE

参见演示http://sqlfiddle.com/#!9/a19fc5/14

答案 1 :(得分:0)

模式A:要在电子商务中搜索数字:

WHERE FIELD(1, '1,2,3,4,5,6,7,8,9,10,11,12,13')

或者

WHERE '1,2,3,4,5,6,7,8,9,10,11,12,13' REGEXP '[[:<:]]1[[:>:]]'

这将检查&#34; 1&#34;被&#34;字边界包围&#34;。

模式B:不容易。

模式C:

WHERE CONCAT(',', 'dolor, sit amet, etc', ',') REGEXP ', *sit amet *,';

这用逗号表示,然后检查可选择用空格包围的单词,然后用逗号表示。