我遇到了查询问题。我使用mysql作为DB。我想使用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 |
到目前为止我尝试过的查询
答案 0 :(得分:0)
使用一个正则表达式可能有一种方法可以做到这一点,但我发现使用三个更容易:
select *
from a
where description regexp '[a-zA-Z ]+[0-9]+[a-zA-Z ]+[0-9]+' and
(description not regexp '[0-9]+[^0-9]+[0-9]+[^0-9]+[0-9]+' or
description regexp '[0-9]+[^0-9]+[0-9]+[^0-9]+[0-9]+/[0-9]+'
);
编辑:
我没有意识到目标仅针对2
,而不是任何数字。这符合您的规则,但不符合您的结果(4不属于):
select *
from a
where description regexp '[a-zA-Z ]+[2]+[a-zA-Z ]+[2]+' and
(description not regexp '[2]+[^0-9]+[2]+[^0-9]+[2]+' or
description regexp '[2]+[^0-9]+[2]+[^0-9]+2/2'
);
答案 1 :(得分:0)
我提出这个正则表达式:
^([^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]+[[:>:]])*$'
正则表达式细分
正则表达式实际上使用了许多重复部分,所以这就是为什么它有点长:
^ # 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 强>
( # Open group
[[:>:]] # Word boundary
| # Or
[a-z] # Letter/alphabet
) # Close group
单词边界与单词的开头和结尾相匹配。这里一个单词的定义是一系列字母,数字和下划线字符。
[[:<:]]
是一个开头的单词边界,因此在单词的开头匹配。
[[:>:]]
是一个开头的单词边界,因此在一个单词的末尾匹配。
它们的使用可确保2
(以及数字/数字部分)不被其他数字包围(例如,使21
失败)或计算2
如果你有例如21/4
作为字符串中两个2
的计数。