Простой способ удалить несколько пробелов в строке в Python

Предположим, что это строка:

The fox jumped over the log. 

Это приведет к:

 The fox jumped over the log. 

Что такое простейший, 1-2 лайнер, который может это сделать? Без разделения и включения в списки …

  • Множественный символ заменить на Python
  • python json dump writeability "не умеет писать"
  • Использует ли Python фрагмент по ссылке на строки?
  • Как удалить все целочисленные значения из списка в python
  • измените некоторые строчные буквы на верхний регистр строки
  • Удалить первый символ строки
  • Python - Присоединиться к новой строке
  • Сравнение строк Python - проблемы со специальными / Unicode-символами
  • 16 Solutions collect form web for “Простой способ удалить несколько пробелов в строке в Python”

     >>> import re >>> re.sub(' +',' ','The quick brown fox') 'The quick brown fox' 

    foo – ваша строка:

     " ".join(foo.split()) 

    Будьте осторожны, хотя это удаляет «все пробельные символы (пробел, табуляция, символ новой строки, return, formfeed)». (Спасибо hhsaffar , см. Комментарии), т.е. "this is \ta test\n" будет эффективно заканчиваться как "this is a test"

     import re s = "The fox jumped over the log." re.sub("\s\s+" , " ", s) 

    или

     re.sub("\s\s+", " ", s) 

    так как пространство перед запятой указано как домашнее животное в PEP8, как упоминалось лосом в комментариях.

    Использование регулярных выражений с помощью «\ s» и выполнение простых string.split () также удаляют другие пробелы – например, строки новой строки, возврат каретки, вкладки. Если это не требуется, чтобы делать только несколько пробелов , я представляю эти примеры.


    EDIT: Как я привык делать, я спал на этом, и, кроме исправления опечатки на последних результатах (v3.3.3 @ 64-бит, а не 32-битный), очевидное поразило меня: тестовая строка была довольно тривиальной ,

    Итак, я получил … 11 абзацев, 1000 слов, 6665 байт Lorem Ipsum, чтобы получить более-реалистичные тесты времени. Затем я добавил дополнительные пробелы по всей длине:

     original_string = ''.join(word + (' ' * random.randint(1, 10)) for word in lorem_ipsum.split(' ')) 

    Я также исправил «правильное join »; если кто-то заботится, однострочный слой будет по существу делать полосу любых ведущих / конечных пространств, эта исправленная версия сохраняет ведущее / конечное пространство (но только ONE ;-). (Я нашел это, потому что случайный lorem_ipsum получил дополнительные пробелы на конце и, таким образом, не смог assert .)


     # setup = ''' import re def while_replace(string): while ' ' in string: string = string.replace(' ', ' ') return string def re_replace(string): return re.sub(r' {2,}' , ' ', string) def proper_join(string): split_string = string.split(' ') # To account for leading/trailing spaces that would simply be removed beg = ' ' if not split_string[ 0] else '' end = ' ' if not split_string[-1] else '' # versus simply ' '.join(item for item in string.split(' ') if item) return beg + ' '.join(item for item in split_string if item) + end original_string = """Lorem ipsum ... no, really, it kept going... malesuada enim feugiat. Integer imperdiet erat.""" assert while_replace(original_string) == re_replace(original_string) == proper_join(original_string) #''' 

     # while_replace_test new_string = original_string[:] new_string = while_replace(new_string) assert new_string != original_string 

     # re_replace_test new_string = original_string[:] new_string = re_replace(new_string) assert new_string != original_string 

     # proper_join_test new_string = original_string[:] new_string = proper_join(new_string) assert new_string != original_string 

    ПРИМЕЧАНИЕ . «В while версия» сделала копию original_string , как я считаю, когда она была изменена в первом прогоне, последовательные прогоны будут быстрее (хотя бы бит). Поскольку это добавляет время, я добавил эту строковую копию к двум другим, чтобы времена показывали разницу только в логике. Имейте в виду, что основные экземпляры stmt on timeit будут выполняться только один раз ; оригинальный способ, которым я это сделал, цикл while работал на том же ярлыке, original_string , таким образом, второй запуск, делать нечего. Теперь, когда он настроен, вызывая функцию, используя две разные метки, это не проблема. Я добавил утверждения всем рабочим, чтобы проверить, что мы что-то изменяем на каждой итерации (для тех, кто может быть сомнительным). Например, измените это, и он сломается:

     # while_replace_test new_string = original_string[:] new_string = while_replace(new_string) assert new_string != original_string # will break the 2nd iteration while ' ' in original_string: original_string = original_string.replace(' ', ' ') 

     Tests run on a laptop with an i5 processor running Windows 7 (64-bit). timeit.Timer(stmt = test, setup = setup).repeat(7, 1000) test_string = 'The fox jumped over\n\t the log.' # trivial Python 2.7.3, 32-bit, Windows test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.001066 | 0.001260 | 0.001128 | 0.001092 re_replace_test | 0.003074 | 0.003941 | 0.003357 | 0.003349 proper_join_test | 0.002783 | 0.004829 | 0.003554 | 0.003035 Python 2.7.3, 64-bit, Windows test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.001025 | 0.001079 | 0.001052 | 0.001051 re_replace_test | 0.003213 | 0.004512 | 0.003656 | 0.003504 proper_join_test | 0.002760 | 0.006361 | 0.004626 | 0.004600 Python 3.2.3, 32-bit, Windows test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.001350 | 0.002302 | 0.001639 | 0.001357 re_replace_test | 0.006797 | 0.008107 | 0.007319 | 0.007440 proper_join_test | 0.002863 | 0.003356 | 0.003026 | 0.002975 Python 3.3.3, 64-bit, Windows test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.001444 | 0.001490 | 0.001460 | 0.001459 re_replace_test | 0.011771 | 0.012598 | 0.012082 | 0.011910 proper_join_test | 0.003741 | 0.005933 | 0.004341 | 0.004009 

     test_string = lorem_ipsum # Thanks to http://www.lipsum.com/ # "Generated 11 paragraphs, 1000 words, 6665 bytes of Lorem Ipsum" Python 2.7.3, 32-bit test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.342602 | 0.387803 | 0.359319 | 0.356284 re_replace_test | 0.337571 | 0.359821 | 0.348876 | 0.348006 proper_join_test | 0.381654 | 0.395349 | 0.388304 | 0.388193 Python 2.7.3, 64-bit test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.227471 | 0.268340 | 0.240884 | 0.236776 re_replace_test | 0.301516 | 0.325730 | 0.308626 | 0.307852 proper_join_test | 0.358766 | 0.383736 | 0.370958 | 0.371866 Python 3.2.3, 32-bit test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.438480 | 0.463380 | 0.447953 | 0.446646 re_replace_test | 0.463729 | 0.490947 | 0.472496 | 0.468778 proper_join_test | 0.397022 | 0.427817 | 0.406612 | 0.402053 Python 3.3.3, 64-bit test | minum | maximum | average | median ---------------------+------------+------------+------------+----------- while_replace_test | 0.284495 | 0.294025 | 0.288735 | 0.289153 re_replace_test | 0.501351 | 0.525673 | 0.511347 | 0.508467 proper_join_test | 0.422011 | 0.448736 | 0.436196 | 0.440318 

    Для тривиальной строки казалось бы, что цикл while является самым быстрым, за которым следует Pythonic string-split / join и regex, потянув за тыл.

    Для нетривиальных строк , кажется, есть немного больше, чтобы рассмотреть. 32-битный 2,7? Это регулярное выражение для спасения! 2.7 64-бит? Лучше всего использовать замкнутый цикл, с достаточной степенью защиты. 32-бит 3.2, переходите к «правильному» join . 64-бит 3.3, перейдите в цикл while. Еще раз.

    В конце концов, можно улучшить производительность, если / где / когда это необходимо , но всегда лучше помнить мантру :

    1. Сделай так, чтоб это работало
    2. Сделать это правильно
    3. Сделай это быстро

    IANAL, YMMV, Caveat Emptor!

    Согласитесь с вышеприведенным комментарием Пола Макгуайра. Мне,

      ' '.join(the_string.split()) 

    гораздо предпочтительнее вырвать регулярное выражение. Мои измерения (Linux, Python 2.5) показывают, что split-then-join почти в 5 раз быстрее, чем «re.sub (…)», и все еще в 3 раза быстрее, если вы предварительно скомпилируете регулярное выражение один раз и выполните операцию много раз. И это легче понять – гораздо более питоновское.

    Подобно предыдущим решениям, но более конкретным: замените два или более пробела на один:

     >>> import re >>> s = "The fox jumped over the log." >>> re.sub('\s{2,}', ' ', s) 'The fox jumped over the log.' 

    Простая душа

     >>> import re >>> s="The fox jumped over the log." >>> print re.sub('\s+',' ', s) The fox jumped over the log. 

    Другая альтернатива

     >>> import re >>> str = 'this is a string with multiple spaces and tabs' >>> str = re.sub('[ \t]+' , ' ', str) >>> print str this is a string with multiple spaces and tabs 

    Одна строка кода для удаления всех лишних пробелов до, после и внутри предложения:

     sentence = " The fox jumped over the log. " sentence = ' '.join(filter(None,sentence.split(' '))) 

    Объяснение:

    1. Разделите всю строку в список.
    2. Фильтровать пустые элементы из списка.
    3. Объединить оставшиеся элементы * с одним пространством

    * Остальные элементы должны быть словами или словами с пунктуациями и т. Д. Я не тестировал это широко, но это должно быть хорошей отправной точкой. Всего наилучшего!

    Это также работает:

     while " " in s: s=s.replace(" "," ") 

    Где переменная s представляет вашу строку.

     def unPretty(S): # given a dictionary, json, list, float, int, or even a string.. # return a string stripped of CR, LF replaced by space, with multiple spaces reduced to one. return ' '.join( str(S).replace('\n',' ').replace('\r','').split() ) 

    Если это пробел, который вы имеете в отношении разделения на None, в возвращаемое значение не будет включена пустая строка.

    https://docs.python.org/2/library/stdtypes.html#str.split

     string='This is a string full of spaces and taps' string=string.split(' ') while '' in string: string.remove('') string=' '.join(string) print(string) 

    результаты :

    Это строка, полная пробелов и кранов

    Чтобы удалить пробел, учитывая ведущее, конечное и дополнительное свободное пространство между словами, используйте:

    (? <= \ s) + | ^ + (? = \ s) | (? = + [\ n \ 0])

    первый или имеет дело с ведущим пробелом, второй или имеет дело с началом строки, ведущим пробелом, а последний имеет дело с завершающим пробелом

    для доказательства использования эта ссылка предоставит вам тест.

    https://regex101.com/r/meBYli/4

    сообщите мне, если вы найдете вход, который нарушит этот код регулярного выражения.

    ТАКЖЕ – это должно использоваться с функцией re.split

    В некоторых случаях желательно заменить последовательные вхождения каждого символа пробела одним экземпляром этого символа. Для этого вы должны использовать регулярное выражение с обратными ссылками.

    (\s)\1{1,} соответствует любому символу пробела, за которым следует одно или несколько вхождений этого символа. Теперь все, что вам нужно сделать, это указать первую группу ( \1 ) в качестве замены для соответствия.

    Обертывание этого в функции:

     import re def normalize_whitespace(string): return re.sub(r'(\s)\1{1,}', r'\1', string) 
     >>> normalize_whitespace('The fox jumped over the log.') 'The fox jumped over the log.' >>> normalize_whitespace('First line\t\t\t \n\n\nSecond line') 'First line\t \nSecond line' 

    import re string = re.sub ('[\ t \ n] +', '', 'Быстрое коричневое \ n \ n \ t fox')

    Это позволит удалить все вкладки, новые строки и несколько пробелов с одним пробелом.

    Python - лучший язык программирования в мире.