Tôi đề xuất regex này:
^([^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]+[[:>:]])*$
Nó hơi dài, nhưng nó cho phép linh hoạt hơn trong đó những chuỗi đó cũng được coi là 'hợp lệ':
(2/2) 2new 2new
2new (2/2) 2new (2/2)
Trong mã
SELECT
*
FROM
A
WHERE
description REGEXP '^(([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*2([[:>:]]|[a-z])){2}([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*$'
Phân tích Regex
Thực tế regex sử dụng nhiều phần lặp lại, vì vậy đó là lý do tại sao nó hơi dài:
^ # 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
$
Phân tích chi tiết
-
# 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
Ranh giới từ khớp với phần đầu và phần cuối của từ. Định nghĩa của một từ ở đây là một chuỗi các bảng chữ cái, số và ký tự gạch dưới.
[[:<:]]
là ranh giới từ mở đầu và do đó khớp ở đầu từ.
[[:>:]]
là ranh giới từ mở đầu và do đó khớp ở cuối từ.
Việc sử dụng chúng ở đây đảm bảo rằng 2
(và các phần số / số) không được bao quanh bởi các số khác (do đó tạo nên 21
chẳng hạn như thất bại) hoặc đếm một 2
nếu bạn có ví dụ 21/4
là một trong số đó được tính vào hai 2
s trong chuỗi.