Хочу поделиться компактной функцией для очищения лишних, повторяющихся пробелов и пробельных символов в строках. Не считайте это призывом, но если можно привести строковые данные в красивый вид без лишних хлопот, то почему бы и не воспользоваться. Те, кто не знаком с регулярными выражениями (regular expressions, RegExp, regex), может приоткроет форточку в этот славный и замороченный мир (Регулярные выражения (regexp) — основы)
Начнём издалека. Excel СЖПРОБЕЛЫ()
Есть функция в Excel СЖПРОБЕЛЫ(), цитирую Excel, Функция СЖПРОБЕЛЫ, support.microsoft.com
Удаляет из текста все пробелы, за исключением одиночных пробелов между словами. Функция СЖПРОБЕЛЫ используется для обработки текстов, полученных из других прикладных программ, если эти тексты могут содержать лишние пробелы.
Иными словами был текст, наполненный пробелами " Съешь ещё этих мягких французских булок, да выпей чаю " А функция СЖПРОБЕЛЫ() вернёт нормальный текст без пробелов в конце и начале строки, а все двойные, тройные и прочие пробелы между словами преобразуются в один единственный пробел: "Съешь ещё этих мягких французских булок, да выпей чаю".
Моя личная предыстория
Т.к. в свою бытность часто приходилось контактировать с пользовательскими данными от самих пользователей (т.е. какого-либо id в выгрузках в большинстве случаев не существовало), то приходилось ВПР-ить (иначе говоря: JOIN-ить, смапить (лично слышал много раз, за правильность применения термина не ручаюсь)) строчные значения от тех же или иных пользователей из другой выгрузки и первичная очистка строки для ВПР() при помощи СЖПРОБЕЛЫ() просто превратилась в неотъемлемую процедуру.
Хоть функция СЖПРОБЕЛЫ() крайне облегчало жизнь и уменьшало потерю не найденных записей, однако не редко в выгрузках по >100k строк встречались строковые записи с пробельным символом (например: табуляция, неразрывный пробел), которые не обрабатывались функцией СЖПРОБЕЛЫ(). В версиях Excel по 2016 пробельные символы пропускались, про 2019 не могу ничего конкретного сказать, в текущей версии 365 пробельные символы вычищаются. Соответственно, все встречаемые пробельные символы нужно было предварительно обрабатывать вручную.
Позже подобная проблематика всплыла уже в разработке и особенно острой встала в наполнении пользовательских справочников.
Источник проблемы
Пользователь может сам вручную заполнить текст и в процессе заполнения случайно вбить 2 лишних пробела;
Однако, не редко текст для заполнения с пробельными символами уже где-то написан (в Word-е, интернете и пр.) и его просто берут и копируют.
Собственно решение - очищаем
Используем регулярные выражения wikipedia, Регулярные выражения
Все пробельные (в том числе повторяющиеся) символы (\s+) заменяем на пробелы;
Очищаем начало и конец строки от пробелов .strip() / .trim()
Python
import re
def purge(str_in: str) -> str:
"""
Замена всех пробельных (повторяющихся) символов в строке на единичные пробелы
и очистка строки от пробелов в конце и в начале
:param str_in: строка на обработку
:return: обработанная строка
"""
if isinstance(str_in, str):
return re.sub(r"\s+", " ", str_in).strip()
JavaScript
function purge(str_in) {
// Замена всех пробельных (и повторяющихся) символов в строке на единичные пробелы
// и очистка строки от пробелов в конце и в начале
return str_in.replace(/\s+/g, " ").trim();
}
VBS
Function purge(str_in)
' Замена всех пробельных (и повторяющихся) символов в строке на единичные пробелы
' и очистка строки от пробелов в конце и в начале
Set objRegExp = CreateObject("VBScript.RegExp")
With objRegExp
.Pattern = "\s+"
.Multiline = True
.Global = True
End With
purge = Trim(objRegExp.Replace(str_in, " "))
End Function
Вдохновлено: stackoverflow, Regex to replace multiple spaces with a single space
Escape-последовательность "\s"
Не смогу ответить за все реализации RegExp на всех языках, но судя по wikipedia, Регулярные выражения Под "\s" подразумеваются все ниже перечисленные Escape-последовательности:
Символ | Эквивалент |
---|---|
\f | Знак новой страницы |
\n | Знак перевода строки |
\r | Знак возврата каретки |
\t | Знак табуляции |
\v | Знак вертикальной табуляция |
learn.microsoft.com, Escape-последовательности
Заключительное слово
В одном из наших проектов этот метод / функция прочно закрепилась в функционале, тем самым "защитив" от пользователей базу данных в тех местах, где от них ожидался текст размером с один абзац; т.е. (подчёркиваю) НЕ в тех случаях, когда от пользователя ожидалось "сочинение", разбитое по абзацам.

Спасибо за внимание!