Intereting Posts
База данных PK-FK для будущих записей? pyodbc – Как выполнить оператор select с использованием переменной для параметра Пара ключевых значений в реляционной базе данных MSAccess: выберите N записей из каждой категории SQL-подсчет 90-дневных пробелов между записями HQL vs. SQL / Hibernate netbeans Редактор HQL Результаты группового запроса по месяцам и годам в postgresql Как вставить в таблицу из другой таблицы путем сопоставления значений? Обновление столбца varchar до типа перечисления в postgresql Выберите строки с максимальным значением, сгруппированные по двум столбцам SQL Performance UNION против OR SQL, как преобразовать строку с диапазоном дат во многие строки с каждой датой Преимущества ограничения внешнего ключа SQL Server Как я могу «слить», «сгладить» или «поворот» в результате запроса, который возвращает несколько строк в один результат? преобразование десятичного в шестнадцатеричное в sql server 2008

Match Regex в MySQL для повторного слова с условием исключает круглые скобки

У меня проблема с запросом. Я использую 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 | 

запрос, который я пробовал до сих пор

http://sqlfiddle.com/#!2/a227b/2

Я предлагаю это регулярное выражение:

 ^([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])*([[:<:]]|[az])2([[:>:]]|[az])([^2]|[[:<:]][0-9]+/[0-9]+[[:>:]])+([[:<:]]|[az])2([[:>:]]|[az])([^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([[:>:]]|[az])){2}([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])*$' 

SQLFiddle

Распределение регулярных выражений

В регулярном выражении на самом деле используется много повторяющихся частей, поэтому он немного длинный:

 ^ # Beginning of string ( # Open repeat group ([^2]+|[[:<:]][0-9]+/[0-9]+[[:>:]])* # Any characters. See #1 2 # 2 ([[:>:]]|[az]) # 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 [az] # Letter/alphabet ) # Close group 

Граница слов соответствует началу и концу слов. Определение слова здесь представляет собой серию алфавитов, цифр и символов подчеркивания.

[[:<:]] является границей открытого слова и, таким образом, совпадает с началом слова.

[[:>:]] является границей открытого слова и, таким образом, совпадает в конце слова.

Их использование здесь гарантирует, что 2 (и числовые / числовые части) не будут окружены другими числами (следовательно, это приведет к неудаче 21 ) или подсчитайте 2 если у вас есть, например, 21/4 как один, который учитывает два Струна.

Вероятно, есть способ сделать это с одним регулярным выражением, но мне легче использовать три:

 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' );