Как получить все подходящие слова, кроме слов в скобках? 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}

http://regexr.com/3dhsl

Мне нужно получить данные с помощью оператора 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);
Другие вопросы по тегам