MySQL正则表达式匹配包含某些字段的多个CSV行

时间:2016-01-17 06:52:17

标签: php mysql regex csv

我想使用MySQL的REGEXP来匹配MySQL查询中的多个csv号码。

我正在尝试识别CSV字符串是否包含数字2和9.顺序对结果很重要。它们可以背靠背,并在开始和/或结束时出现。

以下CSV字符串应该都会产生正面结果:

  

1, 2 下,3,4,5,6,7,8,的 9 下,10
  的 2 下,的 9 下,1,2,3,4,5,10
  的 1 下,2,3,5,的 9

这些CSV字符串不应该:

  

9 ,2,3,4,5,10 - (2在9之前不存在)
   2 ,1,2,3,4,5,10 - (9不存在)

我试图通过以下逻辑来匹配我期望的模式:

  1. 匹配任何内容
  2. 至少匹配一次数字
  3. 匹配任何内容
  4. 至少匹配一次9号
  5. 匹配任何内容
  6. 我的表达很接近但不起作用是:

    REGEXP '.*([^0-9][2][^0-9])+.*([^0-9][9][^0-9])+.*'
    

    如果2是字符串的最开头或9,则上面的表达式无法匹配。感谢您的投入。

2 个答案:

答案 0 :(得分:1)

这个怎么样?

(^|(.*\D))2\D(.*[\D]){0,1}9($|\D.*)

查看此RegEx-Demo

中的单元测试
  • (^|(.*\D)) - 字符串的开头或以0-9结尾的内容。
  • 2 - 我们首先需要2个!
  • \D(.*[\D]){0,1}匹配“,”(2和9之后直接匹配,如2,9)或“,......,”
  • 9 - 我们在2之后需要9。
  • ($|\D.*) - 以0-9
  • 开头的单词或其他内容的结尾

答案 1 :(得分:0)

<强>的MySQL

由于我们使用MySQL REGEXP,我们可以采用这种方法:

SELECT * FROM table WHERE field REGEXP '[[:<:]]2[[:>:]].*[[:<:]]9[[:>:]]'

假设每行只有一行CSV,则匹配:

1,2,3,4,5,6,7,8,9,10
2,9,1,2,3,4,5,10
1,2,3,5,9

不匹配:

9,2,3,4,5,10
2,1,2,3,4,5,10
20,9,1,2,3,4,5,10
2,19,1,2,3,4,5,10

在MySQL中,[[:<:]][[:>:]]匹配“单词”的开头和结尾,,不是“单词的一部分”(但每个旁边有两个数字)其他被认为是“单词”。

例如:

mysql> SELECT * FROM test WHERE csv REGEXP '[[:<:]]2[[:>:]].*[[:<:]]9[[:>:]]';
+----+----------------------+
| id | csv                  |
+----+----------------------+
|  1 | 1,2,3,4,5,6,7,8,9,10 |
+----+----------------------+
1 row in set (0.00 sec)

<强> PCRE

我原本以为这是一个PCRE问题,但这是一个MySQL REGEXP问题!但是,如果有人发现它有用,我会在这里留下关于PCRE的信息。

This regex基本上等同于上面的MySQL REGEXP

^.*\b2\b.*\b9\b.*$

使用上面的链接可以帮助您直观地看到匹配。

\b是一个“单词边界”(与MySQL中的[[:<:]][[:>:]]基本相同),阻止我们匹配其他数字的数字。< / p>

注意,如果您尝试一次匹配整个多行文本块,请使用m PCRE修饰符(PCRE_MULTILINE标志),以便^和{{ 1}}锚定在每一行的开头和结尾,而不是整个字符串。

所以,在PHP中,我们使用:

$

或者:

preg_match('/^.*\b2\b.*\b9\b.*$/', $csvRow);