PostgreSQL подсчитывает количество раз, когда подстрока встречается в тексте

Вопрос:Я пишу функцию PostgreSQL для подсчета количества раз, когда определенная текстовая подстрока встречается в другом фрагменте текста. Например, вызов count ('foobarbaz', 'ba') должен возвращать 2. Я понимаю, что для проверки наличия подстроки я использую условие, подобное приведенному ниже: WHERE 'foobarbaz' like '%ba%' Однако мне нужно, чтобы он возвращал 2 для количества раз "ba". Как я

Вопрос:

Я пишу функцию PostgreSQL для подсчета количества раз, когда определенная текстовая подстрока встречается в другом фрагменте текста. Например, вызов count (‘foobarbaz’, ‘ba’) должен возвращать 2.

Я понимаю, что для проверки наличия подстроки я использую условие, подобное приведенному ниже:

WHERE ‘foobarbaz’ like ‘%ba%’

Однако мне нужно, чтобы он возвращал 2 для количества раз “ba”. Как я могу продолжить?

Заранее благодарим за помощь.

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

Я бы настоятельно рекомендовал проверить этот ответ, который я отправил в “Как вы считаете появление привязанной строки с помощью PostgreSQL?” . Было показано, что выбранный ответ был значительно медленнее, чем адаптированный вариант regexp_replace(). Накладные расходы на создание строк и запуск агрегата просто слишком высоки.

Самый быстрый способ сделать это следующий:

SELECT (length(str) — length(replace(str, replacestr, »)) )::int / length(replacestr) FROM ( VALUES (‘foobarbaz’, ‘ba’) ) AS t(str, replacestr);

Здесь мы

  • Возьмите длину строки, L1
  • Вычесть из L1 длину строки со всеми удаленными заменами L2, чтобы получить L3 разницу в длине строки.
  • Разделите L3 на длину замены, чтобы получить вхождения

Для сравнения: в пять раз быстрее, чем метод использования regexp_matches(), который выглядит следующим образом.

SELECT count(*) FROM ( VALUES (‘foobarbaz’, ‘ba’) ) AS t(str, replacestr) CROSS JOIN LATERAL regexp_matches(str, replacestr, ‘g’); Ответ №1

Как использовать регулярное выражение:

SELECT count(*) FROM regexp_matches(‘foobarbaz’, ‘ba’, ‘g’);

Флаг ‘g’ повторяет несколько совпадений строки (а не только первой).

Ответ №2

Существует

str_count( src, occurence )

на основе

SELECT (length( str ) — length(replace( str, occurrence, » ))) / length( occurence )

и a

str_countm( src, regexp )

на основе упомянутого @MikeT

SELECT count(*) FROM regexp_matches( str, regexp, ‘g’)

можно найти здесь: postgres-utils

Ответ №3

Попробуйте:

SELECT array_length (string_to_array (‘1524215121518546516323203210856879’, ‘1’), 1) — 1 —RESULT: 7

Оцените статью
Добавить комментарий