Предлагам този регулярен израз:
^([^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
s в низа.