Как подсчитать слова в MySQL/заменителе регулярных выражений?
-
20-09-2019 - |
Вопрос
Как я могу в запросе MySQL вести себя так же, как функция Regex.Replace (например, в .NET/C#)?
Мне это нужно, потому что, как и многие люди, я хотел бы посчитать количество слов в поле.Однако меня не устраивает следующий ответ (данный несколько раз на этом сайте):
SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', '') +1 FROM table
Потому что это не дает хороших результатов, если между двумя словами есть более одного пробела.
Кстати, я думаю, что функция Regex.Replace может быть интересной, поэтому приветствуются все хорошие идеи!
Решение
REGEXP_REPLACE доступен как Пользовательские функции MySQL.
Подсчет слов:Если вы можете контролировать данные, поступающие в базу данных, вы можете удалить двойные пробелы перед вставкой.Кроме того, если вам приходится часто обращаться к подсчету слов, вы можете вычислить его один раз в своем коде и сохранить счетчик в базе данных.
Другие советы
ОБНОВЛЯТЬ:Сейчас добавили отдельный ответ для MySQL 8.0+, который следует использовать предпочтительно.(Сохранен этот ответ на случай, если вы будете ограничены использованием более ранней версии.)
Почти дубликат этот вопрос но в этом ответе будет рассмотрен вариант использования подсчета слов на основе расширенной версии специального заменителя регулярных выражений из этот пост в блоге.
Демо
Для примера текста это дает значение 61 — то же самое, что и все онлайн-счетчики слов, которые я пробовал (например, https://wordcounter.net/).
SQL (исключая функциональный код для краткости):
SELECT txt,
-- Count the number of gaps between words
CHAR_LENGTH(txt) -
CHAR_LENGTH(reg_replace(txt,
'[[:space:]]+', -- Look for a chunk of whitespace
'^.', -- Replace the first character from the chunk
'', -- Replace with nothing (i.e. remove the character)
TRUE, -- Greedy matching
1, -- Minimum match length
0, -- No maximum match length
1, -- Minimum sub-match length
0 -- No maximum sub-match length
))
+ 1 -- The word count is 1 more than the number of gaps between words
- IF (txt REGEXP '^[[:space:]]', 1, 0) -- Exclude whitespace at the start from count
- IF (txt REGEXP '[[:space:]]$', 1, 0) -- Exclude whitespace at the end from count
AS `word count`
FROM tbl;
Ответ: нет, вы не можете иметь такое же поведение в MySQL.
Но я рекомендую вам проверить это раньше вопрос по теме, которая ссылается на UDF, которая предположительно обеспечивает некоторые из этих функций.
MySQL 8.0 теперь обеспечивает достойную REGEXP_REPLACE функция, которая делает это намного проще:
SQL
SELECT -- Count the number of gaps between words
CHAR_LENGTH(txt) -
CHAR_LENGTH(REGEXP_REPLACE(
txt,
'[[:space:]]([[:space:]]*)', -- A chunk of one or more whitespace characters
'$1')) -- Discard the first whitespace character and retain the rest
+ 1 -- The word count is 1 more than the number of gaps between words
- IF (txt REGEXP '^[[:space:]]', 1, 0) -- Exclude whitespace at the start from count
- IF (txt REGEXP '[[:space:]]$', 1, 0) -- Exclude whitespace at the end from count
AS `Word count`
FROM tbl;
Демо