Шаблоны регулярных выражений для соответствия разным типам данных

0

У меня есть текстовое поле базы данных (mysql) с разными данными:

  • data1 - отдельные числа, разделенные запятыми: 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15... n (где n может быть любым положительным целым числом )

  • data2 - текст, разделенный запятой: Lorem ipsum, dolor, sit amet, consectetur, adipiscing, elit, Ut et, sollicitudin, enim, vel, consectetur lacus

В данных не допускается пусковая и конечная запятая, пробелы могут начинаться и/или начинаться с запятой или после запятой, например, 2,3, 4,5, 6,7 или Lorem ipsum, dolor, sit amet и т.д., Которые могут теперь пробелы счет в матче.

Мне нужно искать по-разному в этих данных, поэтому мне нужны шаблоны регулярных выражений для использования с поиском:

  • pattern A: соответствие числа в data1. если я ищу 1, в результате мне просто нужно 1, а не 11, 12 и т.д.

прямо сейчас у меня есть: [0-9]+(,[0-9]+)*

  • pattern B: для соответствия диапазону чисел: если поле содержит (по крайней мере, одно из) числа между двумя заданными числами.
  • шаблон C: для соответствия одной из полных строк, разделенных комами в data2. например: если я ищу сидеть, у меня нет результата, но если я буду сидеть за ситом amet, я получаю результат.

Может ли кто-нибудь помочь мне с этим? Является ли тот, который у меня для Pattern A лучшим способом для этого, и как я могу сопоставить диапазон (шаблон B) и строки с разделителями-запятыми (шаблон C)?

  • 1
    Ваш шаблон Требование выполнимо, но два других, по сути, нет, не без огромных олимпийских усилий по SQL. Что вы должны сделать здесь, чтобы нормализовать ваши данные. Получить каждый идентификатор и текстовую запись в отдельной строке, с цифрами и текстом в отдельных столбцах. Это хороший дизайн и сделает вашу жизнь намного проще.
  • 0
    К сожалению, это не выполнимо, данные даны, но спасибо
Показать ещё 1 комментарий
Теги:

2 ответа

2
Лучший ответ

Вам не нужно регулярное выражение.
Я покажу вам трюк, используя генератор чисел MySQL в сочетании с вложенными функциями SUBSTRING_INDEX.
если вам нужно поддерживать больше CSV, добавьте новый

   CROSS JOIN (
      SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
    ) AS record_[number]

запрос

Этот запрос будет генерировать числа от 1 до 100. Таким образом, окончательный запрос может поддерживать до 100 отдельных значений.

SELECT 
 (@number  := @number + 1) AS number
FROM (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_1
CROSS JOIN (
  SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) AS record_2
CROSS JOIN ( SELECT @number := 0 ) AS init_user_param

см. демо http://sqlfiddle.com/#!9/c314ca/5

Теперь мы собираемся извлечь значения из строки, разделенной запятыми, с помощью

запрос

Замените [position] на число от 0 -... какое значение вы хотите извлечь из разделенных запятыми строк.

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4,5,6,7,8,9,10,11,12,13,14,15', ',', [position]), ',', -1) AS split;

или же

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('Lorem ipsum, dolor, sit amet, consectetur, adipiscing,elit, Ut et, sollicitudin, enim, vel, consectetur lacus ', ',', [position]), ',', -1) AS split;

см. демо http://sqlfiddle.com/#!9/c314ca/16

Теперь мы знаем основы, которые мы собираемся объединить оба запроса с рабочим решением.
Этот запрос преобразует все значения, разделенные запятой, в записи.
Поскольку я не знаю структуру таблицы, я предполагаю, что это что-то вроде

CREATE TABLE [name] (
    data1 TEXT
  , data2 TEXT
); 

запрос

SELECT
  DISTINCT 
      SUBSTRING_INDEX(SUBSTRING_INDEX(data1, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number  := @number + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN
 Table1

UNION ALL 

SELECT
  DISTINCT 
      SUBSTRING_INDEX(SUBSTRING_INDEX(data2, ',', generator.number), ',', -1) AS split
FROM (

  SELECT 
   (@number2  := @number2 + 1) AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS record_2
  CROSS JOIN ( SELECT @number2 := 0 ) AS init_user_param
) 
 AS generator
CROSS JOIN
 Table1

см. демо http://sqlfiddle.com/#!9/a19fc5/6

Мы разбиваем его на маленькие части.

pattern A: соответствие числа в data1. если я ищу 1, в результате мне просто нужно 1, а не 11, 12 и т.д.

Поскольку теперь у нас есть записи вместо значений, разделенных запятыми, мы можем просто использовать последний запрос, поскольку поставленная таблица добавляет предложение WHERE.

см. демо http://sqlfiddle.com/#!9/a19fc5/10

pattern B: для соответствия диапазону чисел: если поле содержит (по крайней мере, одно из) числа между двумя заданными числами.

Теперь предложение WHERE является простым предложением BETWEEN

см. демо http://sqlfiddle.com/#!9/a19fc5/11

шаблон C: для соответствия одной из полных строк, разделенных комами в data2. например: если я ищу сидеть, у меня нет результата, но если я буду сидеть за ситом amet, я получаю результат.

Теперь вы можете использовать LIKE

см. демо http://sqlfiddle.com/#!9/a19fc5/14

0

Образец A: поиск номера в запятой:

WHERE FIELD(1, '1,2,3,4,5,6,7,8,9,10,11,12,13')

Или же

WHERE '1,2,3,4,5,6,7,8,9,10,11,12,13' REGEXP '[[:<:]]1[[:>:]]'

Это проверяет, что "1" окружен "границами слов".

Шаблон B: Нелегко.

Образец С:

WHERE CONCAT(',', 'dolor, sit amet, etc', ',') REGEXP ', *sit amet *,';

Это указывает на запятую, затем проверяет, что слово опционально окружено пробелом (-ами), а затем обязательно запятыми.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню