我有查询问题。我使用mysql作为数据库。我想使用REGEX来匹配我期望的结果,并且该表是
table A ---------------------------------- | ID | Description | ---------------------------------- | 1 | new 2 new 2 new 2 new | | 2 | new 21 new 2 new | | 3 | new 2th 2 (2/2) | | 4 | 2new 2new (2/2) | | 5 | new2 new 2new |
我预期的结果 -数字2只能显示两次 -2之后/之前的字符必须为varchar(空格后除外) -特殊情况:可接受任何模式为“(数字/数字)”的数字,例如ID = 3和ID = 4
| ID | Description | --------------------------------- | 3 | new 2th 2 (2/2) | | 4 | 2new 2new (2/2) | | 5 | new2 new 2new |
到目前为止我尝试过的查询
http://sqlfiddle.com/#!2/a227b/2
我提出这个正则表达式:
^([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])*([[:<:]]|[a-z])2([[:>:]]|[a-z])([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])+([[:<:]]|[a-z])2([[:>:]]|[a-z])([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])*$
它有点长,但是它也提供了更多的灵活性,因为这些字符串也被认为是“有效的”:
(2/2) 2new 2new 2new (2/2) 2new (2/2)
在代码中
SELECT * FROM A WHERE description REGEXP '^(([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*2([[:>:]]|[a-z])){2}([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*$'
SQLFiddle
正则表达式细目
正则表达式实际上使用了很多重复的部分,所以这就是为什么它有点长的原因:
^ # Beginning of string ( # Open repeat group ([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])* # Any characters. See #1 2 # 2 ([[:>:]]|[a-z]) # Word boundary or alphabet/letter. See #2 ){2} # Close repeat group and repeat 2 times ([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])* # Any characters. See #1 $
详细细目
#1
( # Open group
[^2]+ # Any characters except 2
| # OR
[[:<:]] # Open word boundary [0-9]+ # Any numbers / # Forward slash [0-9]+ # Any numbers [[:>:]] # Close word boundary
)* # Close group and repeat any number of times
#2
[[:>:]] # Word boundary | # Or [a-z] # Letter/alphabet ) # Close group
单词边界与单词的开头和结尾匹配。此处单词的定义是一系列字母,数字和下划线字符。
[[:<:]] 是开头的单词边界,因此在单词的开头匹配。
[[:<:]]
[[:>:]] 是开头的单词边界,因此在单词的末尾匹配。
[[:>:]]
在这里它们的使用保证了2(和数字/数字的部分)不被其他数字环绕(因此使21失败的例子)或算一个2,如果你有例如21/4是一种能够对两项罪名2的字符串秒。
2
21
21/4