Ответ 1
Если вы хотите увеличить мощность регулярных выражений в своей базе данных, вы можете использовать LIB_MYSQLUDF_PREG. Это библиотека с открытым исходным кодом пользовательских функций MySQL, которая импортирует библиотеку PCRE. LIB_MYSQLUDF_PREG поставляется только в форме исходного кода. Чтобы использовать его, вам нужно будет скомпилировать его и установить на свой сервер MySQL. Установка этой библиотеки не меняет встроенную поддержку регулярных выражений MySQL. Он просто предоставляет следующие дополнительные функции:
PREG_CAPTURE извлекает регулярное выражение из строки. PREG_POSITION возвращает позицию, в которой регулярное выражение соответствует строке. PREG_REPLACE выполняет поиск и замену строки. PREG_RLIKE проверяет соответствие регулярного выражения строке.
Все эти функции принимают регулярное выражение в качестве первого параметра. Это регулярное выражение должно быть отформатировано как оператор регулярного выражения Perl. Например. чтобы проверить, соответствует ли регулярное выражение объекту без учета регистра, вы должны использовать код MySQL PREG_RLIKE ('/regex/i', subject). Это похоже на PHP preg-функции, для которых также требуются дополнительные//разделители для регулярных выражений внутри строки PHP.
Если вам нужно что-то более простое, вы можете изменить эту функцию в соответствии с вашими потребностями.
CREATE FUNCTION REGEXP_EXTRACT(string TEXT, exp TEXT)
-- Extract the first longest string that matches the regular expression
-- If the string is 'ABCD', check all strings and see what matches: 'ABCD', 'ABC', 'AB', 'A', 'BCD', 'BC', 'B', 'CD', 'C', 'D'
-- It not smart enough to handle things like (A)|(BCD) correctly in that it will return the whole string, not just the matching token.
RETURNS TEXT
DETERMINISTIC
BEGIN
DECLARE s INT DEFAULT 1;
DECLARE e INT;
DECLARE adjustStart TINYINT DEFAULT 1;
DECLARE adjustEnd TINYINT DEFAULT 1;
-- Because REGEXP matches anywhere in the string, and we only want the part that matches, adjust the expression to add '^' and '$'
-- Of course, if those are already there, don't add them, but change the method of extraction accordingly.
IF LEFT(exp, 1) = '^' THEN
SET adjustStart = 0;
ELSE
SET exp = CONCAT('^', exp);
END IF;
IF RIGHT(exp, 1) = '$' THEN
SET adjustEnd = 0;
ELSE
SET exp = CONCAT(exp, '$');
END IF;
-- Loop through the string, moving the end pointer back towards the start pointer, then advance the start pointer and repeat
-- Bail out of the loops early if the original expression started with '^' or ended with '$', since that means the pointers can't move
WHILE (s <= LENGTH(string)) DO
SET e = LENGTH(string);
WHILE (e >= s) DO
IF SUBSTRING(string, s, e) REGEXP exp THEN
RETURN SUBSTRING(string, s, e);
END IF;
IF adjustEnd THEN
SET e = e - 1;
ELSE
SET e = s - 1; -- ugh, such a hack to end it early
END IF;
END WHILE;
IF adjustStart THEN
SET s = s + 1;
ELSE
SET s = LENGTH(string) + 1; -- ugh, such a hack to end it early
END IF;
END WHILE;
RETURN NULL;
END