Ik stel deze regex voor:
^([^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]+[[:>:]])*$
Het is een beetje lang, maar het biedt wat meer flexibiliteit omdat die strings ook als 'geldig' worden beschouwd:
(2/2) 2new 2new
2new (2/2) 2new (2/2)
In code
SELECT
*
FROM
A
WHERE
description REGEXP '^(([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*2([[:>:]]|[a-z])){2}([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*$'
Regex-uitsplitsing
De regex gebruikt eigenlijk veel herhalende delen, dus daarom is het een beetje lang:
^ # 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
$
Gedetailleerd overzicht
-
#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
Een woordgrens komt overeen met het begin en einde van woorden. De definitie van een woord hier is een reeks alfabet, cijfers en onderstrepingstekens.
[[:<:]]
is een beginwoordgrens en komt dus overeen met het begin van een woord.
[[:>:]]
is een beginwoordgrens en komt dus overeen aan het einde van een woord.
Hun gebruik hier zorgt ervoor dat 2
(en de numerieke/numerieke delen) worden niet omringd door andere cijfers (vandaar dat 21
faal bijvoorbeeld) of tel een 2
als je bijvoorbeeld 21/4
. hebt als een die meetelt voor de twee 2
s in de tekenreeks.