Як обрізати пробіли?


1071

Чи існує функція Python, яка буде обробляти пробіл (пробіли та вкладки) з рядка?

Приклад: \t example string\texample string


1
Дякую за голову вгору Я виявив функцію стрічки раніше, але, здається, це не працює на мій внесок.
Кріс,

1
Те саме, що: stackoverflow.com/questions/761804/trimming-a-string-in-python (хоча це питання дещо зрозуміліше, IMHO). Це майже те саме: stackoverflow.com/questions/959215/…
Jonik

6
Python символів вважає, що пробіли зберігаються в string.whitespace.
Джон Фухі

2
Під функцією "стриптиз" ви маєте на увазі метод стриптизу? "Схоже, це не працює для мого введення" Будь ласка, вкажіть свій код, свій вхід та вихід.
S.Lott

5
Можливий дублікат
обрізки

Відповіді:


1599

Пробіл з обох сторін:

s = "  \t a string example\t  "
s = s.strip()

Пробіл справа:

s = s.rstrip()

Пробіл зліва:

s = s.lstrip()

Як вказує thedz , ви можете надати аргумент, щоб позбавити довільних символів будь-якої з таких функцій, як ця:

s = s.strip(' \t\n\r')

Це позбавить будь-який простір, \t, \n, або \rсимволи , з лівого боку, права або обидві сторони рядка.

Наведені вище приклади видаляють лише рядки з лівої та правої частини рядків. Якщо ви також хочете видалити символи з середини рядка, спробуйте re.sub:

import re
print re.sub('[\s+]', '', s)

Це має бути надруковано:

astringexample

18
strip () приймає аргумент, щоб сказати, у що поїхати. Спробуйте: strip ('\ t \ n \ r')
thedz

3
Результати прикладів повинні бути дуже корисними :)
тон

4
Не потрібно перераховувати символи пробілів: docs.python.org/2/library/string.html#string.whitespace
єїс

3
Останній приклад саме такий, як використання str.replace(" ",""). Вам не потрібно використовувати re, якщо у вас є більше місця, тоді ваш приклад не працює. []призначений для позначення одиночних символів, це зайве, якщо ви використовуєте просто \s. Використовуйте або \s+або [\s]+(непотрібними) , але [\s+]не чинить роботу, зокрема , якщо ви хочете замінити кілька прогалин ні з однією , як перетворення "this example" в "this example".
Хорхе Е. Кардона

3
@ JorgeE.Cardona - одне, про що ти злегка помилився - \sбуде містити вкладки, а replace(" ", "")не буде.
ArtOfWarfare

72

trimМетод Python називається strip:

str.strip() #trim
str.lstrip() #ltrim
str.rstrip() #rtrim

5
що легко запам’ятати, оскільки s tri p виглядає майже як tri m.
ісар

22

Для провідних та кінцевих пробілів:

s = '   foo    \t   '
print s.strip() # prints "foo"

В іншому випадку регулярний вираз працює:

import re
pat = re.compile(r'\s+')
s = '  \t  foo   \t   bar \t  '
print pat.sub('', s) # prints "foobar"

1
Ви не склали свій регулярний вираз. Вам потрібно зробити такpat = re.compile(r'\s+')
Еван Фосмарк

Ви, як правило, хочете, щоб sub(" ", s)не ""пізніше з’єднати слова, і ви більше не зможете використовувати їх .split(" ")для маркування.
користувач3467349

було б непогано побачити вихід printтверджень
Рон Кляйн

19

Ви також можете використовувати дуже просту і основну функцію: str.replace () , працює з пробілами та вкладками:

>>> whitespaces = "   abcd ef gh ijkl       "
>>> tabs = "        abcde       fgh        ijkl"

>>> print whitespaces.replace(" ", "")
abcdefghijkl
>>> print tabs.replace(" ", "")
abcdefghijkl

Просто і легко.


2
Але це, на жаль, також прибирає внутрішній простір, тоді як приклад в оригінальному питанні залишає внутрішні простори недоторканими.
Брендон Родос

12
#how to trim a multi line string or a file

s=""" line one
\tline two\t
line three """

#line1 starts with a space, #2 starts and ends with a tab, #3 ends with a space.

s1=s.splitlines()
print s1
[' line one', '\tline two\t', 'line three ']

print [i.strip() for i in s1]
['line one', 'line two', 'line three']




#more details:

#we could also have used a forloop from the begining:
for line in s.splitlines():
    line=line.strip()
    process(line)

#we could also be reading a file line by line.. e.g. my_file=open(filename), or with open(filename) as myfile:
for line in my_file:
    line=line.strip()
    process(line)

#moot point: note splitlines() removed the newline characters, we can keep them by passing True:
#although split() will then remove them anyway..
s2=s.splitlines(True)
print s2
[' line one\n', '\tline two\t\n', 'line three ']

4

Ще ніхто не опублікував ці рішення.

Відповідність:

>>> import re
>>> p=re.compile('\\s*(.*\\S)?\\s*')

>>> m=p.match('  \t blah ')
>>> m.group(1)
'blah'

>>> m=p.match('  \tbl ah  \t ')
>>> m.group(1)
'bl ah'

>>> m=p.match('  \t  ')
>>> print m.group(1)
None

Пошук (ви маєте по-різному обробляти регістр введення "лише пробілів"):

>>> p1=re.compile('\\S.*\\S')

>>> m=p1.search('  \tblah  \t ')
>>> m.group()
'blah'

>>> m=p1.search('  \tbl ah  \t ')
>>> m.group()
'bl ah'

>>> m=p1.search('  \t  ')
>>> m.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

Якщо ви користуєтесь re.sub, ви можете видалити внутрішній пробіл, що може бути небажаним.


3

Пробіл включає простір, вкладки та CRLF . Отже, елегантна та однолінійна струнна функція, яку ми можемо використовувати, - це перекладати .

' hello apple'.translate(None, ' \n\t\r')

АБО якщо ви хочете бути ретельними

import string
' hello  apple'.translate(None, string.whitespace)

3

(re.sub ('+', '', (my_str.replace ('\ n', ''))). strip ()

Це видалить усі небажані пробіли та символи нового рядка. Сподіваюся, що це допоможе

import re
my_str = '   a     b \n c   '
formatted_str = (re.sub(' +', ' ',(my_str.replace('\n',' ')))).strip()

Це призведе до:

'a b \ nc' буде змінено на 'ab c'


2
    something = "\t  please_     \t remove_  all_    \n\n\n\nwhitespaces\n\t  "

    something = "".join(something.split())

вихід:

please_remove_all_whitespaces


Додавши коментар Le Droid до відповіді. Щоб розділити пробіл:

    something = "\t  please     \t remove  all   extra \n\n\n\nwhitespaces\n\t  "
    something = " ".join(something.split())

вихід:

видаліть усі зайві пробіли


1
Простий та ефективний. Можна використовувати "" .join (..., щоб слова розділялися пробілом.
Le Droid

1

Якщо ви використовуєте Python 3: у своїй заяві про друк закінчіть sep = "". Це відокремить усі пробіли.

ПРИКЛАД:

txt="potatoes"
print("I love ",txt,"",sep="")

Це надрукує: Я люблю картоплю.

Замість: Я люблю картоплю.

У вашому випадку, оскільки ви намагаєтеся позбутися \ n, зробіть sep = "\ t"


1

Переглянувши тут досить багато рішень з різним ступенем розуміння, я задумався, що робити, якщо рядок розділяється комами ...

проблема

Намагаючись обробити csv контактної інформації, мені потрібно було вирішити цю проблему: обріжте сторонні пробіли та трохи сміття, але збережіть кінцеві коми та внутрішній пробіл. Працюючи з полем, що містить нотатки про контакти, я хотів прибрати сміття, залишивши хороші речі. Обрізаючи всі розділові знаки і пункти, я не хотів втрачати пробіл між складовими лексемами, оскільки не хотів перебудовуватися пізніше.

регулярний вираз і візерунки: [\s_]+?\W+

Шаблон шукає поодинокі екземпляри будь-якого символу пробілу та підкреслення ('_') від 1 до необмеженої кількості разів ліниво (якомога менше символів), [\s_]+?які стають перед символами без слова, що виникають від 1 до необмеженої кількості час з цим: \W+(еквівалентно [^a-zA-Z0-9_]). Зокрема, це знаходить пробіли пробілів: нульові символи (\ 0), вкладки (\ t), нові рядки (\ n), подання вперед (\ f), повернення каретки (\ r).

Перевагу в цьому я бачу вдвічі:

  1. що він не видаляє пробіл між цілими словами / лексемами, які ви могли б захотіти зберегти разом;

  2. Вбудований метод рядка Python strip()не має стосунку до рядка, лише лівий і правий кінці, а аргумент за замовчуванням - це нульові символи (див. Приклад нижче: декілька нових рядків є в тексті, і strip()він не видаляє їх усіх, поки регенерується шаблон). .text.strip(' \n\t\r')

Це виходить за рамки питання про оперативні програми, але я думаю, що є чимало випадків, коли ми можемо мати незвичайні, патологічні випадки в текстових даних, як я це робив (деякі, як символи втечі опинилися в деяких текстах). Більше того, у рядках, подібних до списку, ми не хочемо ліквідувати роздільник, якщо роздільник не розділяє два символи пробілу або якийсь символ, який не має слова, як '-,' або '-, ,,,'.

NB: Не кажучи про розмежувач самого CSV. Тільки про випадки в CSV, де дані подібні до списку, тобто є cs рядком підрядків.

Повне розкриття: я маніпулював текстом близько місяця, і повторно виражав лише останні два тижні, тому я впевнений, що я пропускаю деякі нюанси. Однак, для менших колекцій рядків (мої знаходяться в кадрі даних 12000 рядків і 40 непарних стовпців), як завершальний крок після пропуску для видалення сторонніх символів, це працює виключно добре, особливо якщо ви вводите деякий додатковий пробіл, де ви хочуть відокремити текст, приєднаний несловним символом, але не хочуть додавати пробіли там, де раніше його не було.

Приклад:

import re


text = "\"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, jim.somedude@blahblah.com, ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, , , , \r, , \0, ff dd \n invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, \n i69rpofhfsp9t7c practice 20ignition - 20june \t\n .2134.pdf 2109                                                 \n\n\n\nklkjsdf\""

print(f"Here is the text as formatted:\n{text}\n")
print()
print("Trimming both the whitespaces and the non-word characters that follow them.")
print()
trim_ws_punctn = re.compile(r'[\s_]+?\W+')
clean_text = trim_ws_punctn.sub(' ', text)
print(clean_text)
print()
print("what about 'strip()'?")
print(f"Here is the text, formatted as is:\n{text}\n")
clean_text = text.strip(' \n\t\r')  # strip out whitespace?
print()
print(f"Here is the text, formatted as is:\n{clean_text}\n")

print()
print("Are 'text' and 'clean_text' unchanged?")
print(clean_text == text)

Цей результат:

Here is the text as formatted:

"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, jim.somedude@blahblah.com, ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf" 

using regex to trim both the whitespaces and the non-word characters that follow them.

"portfolio, derp, hello-world, hello-, world, founders, mentors, ffib, biff, 1, 12.18.02, 12, 2013, 9874890288, ff, series a, exit, general mailing, fr, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk,  jim.somedude@blahblah.com, dd invites,subscribed,, master, dd invites,subscribed, ff dd invites, subscribed, alumni spring 2012 deck: https: www.dropbox.com s, i69rpofhfsp9t7c practice 20ignition 20june 2134.pdf 2109 klkjsdf"

Very nice.
What about 'strip()'?

Here is the text, formatted as is:

"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, jim.somedude@blahblah.com, ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf"


Here is the text, after stipping with 'strip':


"portfolio, derp, hello-world, hello-, -world, founders, mentors, :, ?, %, ,>, , ffib, biff, 1, 12.18.02, 12,  2013, 9874890288, .., ..., ...., , ff, series a, exit, general mailing, fr, , , ,, co founder, pitch_at_palace, ba, _slkdjfl_bf, sdf_jlk, )_(, jim.somedude@blahblah.com, ,dd invites,subscribed,, master, , , ,  dd invites,subscribed, ,, , , ff dd 
 invites, subscribed, , ,  , , alumni spring 2012 deck: https: www.dropbox.com s, 
 i69rpofhfsp9t7c practice 20ignition - 20june 
 .2134.pdf 2109                                                 



klkjsdf"
Are 'text' and 'clean_text' unchanged? 'True'

Таким чином, смужка знімає простір один раз. Так що у випадку з ОП, strip()це добре. але якщо речі стають більш складними, регулярні вирази та подібний зразок можуть мати деяку цінність для більш загальних параметрів.

бачити це в дії


0

спробуйте перекласти

>>> import string
>>> print '\t\r\n  hello \r\n world \t\r\n'

  hello 
 world  
>>> tr = string.maketrans(string.whitespace, ' '*len(string.whitespace))
>>> '\t\r\n  hello \r\n world \t\r\n'.translate(tr)
'     hello    world    '
>>> '\t\r\n  hello \r\n world \t\r\n'.translate(tr).replace(' ', '')
'helloworld'

0

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

some_string = "    Hello,    world!\n    "
new_string = some_string.strip()
# new_string is now "Hello,    world!"

Це дуже добре працює як метод Qt QString :: trimmed (), тим, що він видаляє провідні та відсталі пробіли, залишаючи внутрішній пробіл у спокої.

Але якщо ви хочете щось подібне до методу QString :: спрощений () Qt, який не тільки видаляє пробіли та пробіли пробілів, а й "прив'язує" всі послідовні внутрішні пробіли до одного символу простору, ви можете використовувати комбінацію .split()та " ".join, як це:

some_string = "\t    Hello,  \n\t  world!\n    "
new_string = " ".join(some_string.split())
# new_string is now "Hello, world!"

У цьому останньому прикладі кожна послідовність внутрішнього пробілу замінюється єдиним пробілом, при цьому все ще обрізаючи пробіл від початку та кінця рядка.


-1

Як правило, я використовую такий метод:

>>> myStr = "Hi\n Stack Over \r flow!"
>>> charList = [u"\u005Cn",u"\u005Cr",u"\u005Ct"]
>>> import re
>>> for i in charList:
        myStr = re.sub(i, r"", myStr)

>>> myStr
'Hi Stack Over  flow'

Примітка. Це лише для видалення "\ n", "\ r" та "\ t". Це не видаляє зайві пробіли.


-2

для видалення пробілів з середини струни

$p = "ATGCGAC ACGATCGACC";
$p =~ s/\s//g;
print $p;

вихід:

ATGCGACACGATCGACC

1
це питання стосується python, а не Javascript або perl
phuclv

-17

Це видалить увесь пробіл та нові рядки з початку та кінця рядка:

>>> s = "  \n\t  \n   some \n text \n     "
>>> re.sub("^\s+|\s+$", "", s)
>>> "some \n text"

8
Навіщо використовувати регулярний вираз, коли s.strip()робить саме це?
Нед Батчелдер

1
s.strip()обробляє лише початковий пробіл, а не пробіл, "виявлений" після видалення інших небажаних символів. Зауважте, що це видалить навіть пробіли після остаточного ведучого\n
Рафі

Хтось голосував за цю відповідь, але не пояснив, чому вона хибна. Сором вам (@NedBatchelder, якщо ви голосували проти вас, будь ласка, зворотній шлях, коли я пояснив своє запитання, і ви не згадали нічого, що насправді було порушено моєю відповіддю)
Rafe

10
Рафе, ви можете повторити перевірку: s.strip()дає точно такий же результат, як і ваш регулярний вираз.
Нед Батчелдер

3
@Rafe, ви плутаєте це з обробкою. Strip виконує необхідні операції.
iMitwe
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.