REGEXP_REPLACE заменяет пробелы между двумя символами - PullRequest
0 голосов
/ 08 января 2019

Мне нужно заменить все пробелы на один% между двумя конкретными символами (@ и &); нравится следующее:

'this @ is test   &that did not @turn& out well' 

следует преобразовать в

'this @%is%test%&that did not @turn& out well'

и

'@pattern matching&  is my number one enemy'

до

'@pattern%matching&  is my number one enemy'

Я почти прочитал все связанные вопросы в stackoverflow и на других сайтах, но не смог получить полезный ответ.

1 Ответ

0 голосов
/ 09 января 2019

Один (неэффективный) способ сделать это - сделать несколько вызовов REGEXP_REPLACE.

Например, давайте рассмотрим следующую функцию plpgsql.

CREATE OR REPLACE FUNCTION replaceSpacesBetweenTwoSymbols(startChar TEXT, endChar TEXT, textToParse TEXT)
    RETURNS TEXT
AS $$
DECLARE resultText TEXT := textToParse;
DECLARE tempText TEXT := textToParse;
BEGIN
    WHILE TRUE LOOP
        tempText = REGEXP_REPLACE(resultText,
                                  '(' || startChar || '[^' || endChar || ']*)' || '( )(.*' || endChar || ')',
                                  '\1%\3');
        IF tempText = resultText
        THEN RETURN resultText;
        END IF;
        resultText := tempText;
    END LOOP;
    RETURN resultText;

END;
$$
LANGUAGE 'plpgsql';

Мы создаем функцию, которая принимает три аргумента: startChar, endChar и textToParse, которые содержат текст, который будет обрезан.

Мы начнем с создания регулярного выражения на основе startChar и endChar. Если значение startChar равно @, а значение endChar равно &, мы получим следующее регулярное выражение:

(@[^&]*)( )(.*&)

Это регулярное выражение состоит из трех групп:

  1. (@[^&]*) - эта группа соответствует тексту, который находится между @ и символом пробела - '';

  2. ( ) - эта группа соответствует одному пробелу.

  3. (.*&) - эта группа соответствует тексту, который находится между пробелом и символом &.

Чтобы заменить пробел (группа 2), мы используем следующий REGEXP_REPLACE вызов:

REGEXP_REPLACE(resultText,' (@[^&]*)( )(.*&)', '\1%\3')

Из этого выражения видно, что мы заменяем вторую группу (которая является пробелом) символом %.

Таким образом, мы заменим только один пробел на одно REGEXP_REPLACE выполнение. Как только мы обнаружим, что больше нет пробелов, которые необходимо заменить, мы возвращаем измененный TEXT. На этом этапе пробелы заменяются % символами. Последнее, что нам нужно сделать, - это заменить несколько последовательных % символов одним %.

Это можно сделать с помощью другого REGEXP_REPLACE вызова в конце. Так, например:

SELECT REGEXP_REPLACE(replaceSpacesBetweenTwoSymbols('@','&','this @ is test   &that did not @turn& out well'),'%{2,}','%');

Вернется

этот @% -% теста%, который не получился @ удачным

в результате, а это

SELECT REGEXP_REPLACE(replaceSpacesBetweenTwoSymbols('@','&','this is @a more  complex& task @test a a & w'),'%{2,}','%');

вернется

это @%% сложнее & задача @ test% a% a% & w

в результате.

...