Как получить все подходящие слова, кроме слов в скобках? Regex/Mysql
Вот пример, который я имею:
JELLY2some text
some text{JELLY2}some textsome textsome text
Sample text for testing:
some textJELLY2 {some text JELLY2 lsdkfjsd}にsome text
Я хочу получить все JELLY2
кроме тех, которые в скобках, как:
{JELLY2}
а также
{some text JELLY2 lsdkfjsd}
Мне нужно получить данные с помощью оператора select, что-то вроде:
SELECT `id` FROM `table` WHERE `body` REGEXP 'JELLY2'
Или, может быть, если это возможно с RLIKE или другим способом?
SELECT `id` FROM `table` WHERE `body` RLIKE 'JELLY2'
2 ответа
Используйте отрицательный символьный класс и группы, которые могут пропустить ввод в скобках, чтобы потребовать, чтобы цель не была в скобках, плюс начальный / конечный якоря:
SELECT id
FROM table
WHERE body RLIKE '^([^{]*(\{[^}]*\})?)*JELLY2([^{]*(\{[^}]*\})?)*$'
Смотрите живую демонстрацию.
Хотя маловероятно, что вы могли бы сделать это с помощью регулярного выражения MySQL, и я думаю, что к нему лучше подходить с использованием другого языка, вы могли бы написать функцию MySQL для этого.
Там, наверное, любое количество подходов. Этот зацикливается на все случаи needle
в haystack
, проверяя, является ли количество {
количество символов, предшествующих вхождению, меньше или равно количеству }
символы, предшествующие этому. Это означает, что это не особенно надежно (}}}{JELLY2}
Я бы это запутал) но вы могли бы развить идею дальше, если бы это было проблемой.
DELIMITER //
CREATE FUNCTION contains_text_outside_braces(needle VARCHAR(255), haystack VARCHAR(255))
RETURNS INT DETERMINISTIC
BEGIN
DECLARE pos INT;
DECLARE previous INT DEFAULT 1;
DECLARE length INT DEFAULT LENGTH(needle);
DECLARE prefix VARCHAR(255);
LOOP
SET pos = LOCATE(needle, haystack, previous);
IF pos = 0 THEN
RETURN 0;
END IF;
SET prefix = LEFT(haystack, pos - 1);
IF LENGTH(REPLACE(prefix, '{', '')) >= LENGTH(REPLACE(prefix, '}', '')) THEN
RETURN 1;
END IF;
SET previous = pos + length;
END LOOP;
END//
DELIMITER ;
SELECT * FROM example_table WHERE contains_text_outside_braces('JELLY2', content);