Boşluğu nasıl düzeltirim?


1071

Bir dizeden boşluk (boşluklar ve sekmeler) kesecek bir Python işlevi var mı?

Örnek: \t example string\texample string


1
Söylediğin için teşekkürler. Şerit işlevini daha önce keşfetmiştim, ancak girdilerim için çalışmıyor gibi görünüyor ..
Chris

1
Aynı: stackoverflow.com/questions/761804/trimming-a-string-in-python (bu soru biraz daha açık olsa da, IMHO). Bu da neredeyse aynı: stackoverflow.com/questions/959215/…
Jonik

6
Python'un boşlukta saklandığını düşündüğü karakterler string.whitespace.
John Fouhy

2
"Strip fonksiyonu" ile strip metodu mu demek istediniz? "Girişim için çalışmıyor gibi görünüyor" Lütfen kodunuzu, girişinizi ve çıkışınızı girin.
S.Lott

Yanıtlar:


1599

Her iki tarafta boşluk:

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

Sağ taraftaki boşluk:

s = s.rstrip()

Sol taraftaki boşluk:

s = s.lstrip()

Gibi thedz işaret, böyle bu fonksiyonların herhangi birine keyfi karakterleri şerit bir argüman sağlayabilir:

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

Bu, herhangi bir boşluk şerit olacak, \t, \nveya \rsol taraftan karakterler, sağ taraf, veya dize her iki tarafı.

Yukarıdaki örnekler yalnızca dizelerin sol ve sağ tarafındaki dizeleri kaldırır. Dizenin ortasındaki karakterleri de kaldırmak istiyorsanız şunu deneyin re.sub:

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

Çıktı alınmalıdır:

astringexample

18
strip (), ne seyahate çıkacağını söylemek için bir tartışmaya girer. Deneyin: strip ('\ t \ n \ r')
thedz

3
Örneklerin sonuçları oldukça yardımcı olmalıdır :)
ton

4
Boşluk karakterlerini listelemeye gerek yok: docs.python.org/2/library/string.html#string.whitespace
jesuis

3
Son örnek aynen kullanmak gibidir str.replace(" ",""). reBirden fazla alanınız olmadığı sürece kullanmanıza gerek yoktur , o zaman örneğiniz işe yaramaz. []tek karakterleri işaretlemek için tasarlanmıştır, sadece kullanıyorsanız gereksizdir \s. Kullanım ya \s+ya [\s]+(gereksiz) ama [\s+]iş yapmaz, sen dönüm gibi tek bir ile birden çok boşluğu değiştirmek istiyorsanız özellikle "this example" içine "this example".
Jorge E.Cardona

3
@ JorgeE.Cardona - Biraz yanlış yaptığınız bir şey - olmazsa \ssekmeler içerir replace(" ", "").
ArtOfWarfare

72

Python trimyöntemi denir strip:

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

5
hatırlaması kolaydır, çünkü s tri p neredeyse tri m'ye benzer.
isar

22

Öncü ve sondaki boşluk için:

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

Aksi takdirde, normal bir ifade çalışır:

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

1
Normal ifadenizi derlemediniz. Yapmanız gerekpat = re.compile(r'\s+')
Evan Fosmark

Genellikle istediğiniz sub(" ", s)değil ""sonradan sözcükleri birleştirir ve artık kullanmak mümkün olacak .split(" ")tokenize için.
user3467349

printifadelerin çıktısını görmek güzel olurdu
Ron Klein

19

Ayrıca çok basit ve temel bir işlev de kullanabilirsiniz: str.replace () , boşluklar ve sekmelerle çalışır:

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

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

Basit ve kolay.


2
Ancak bu, ne yazık ki, iç mekanı da kaldırırken, orijinal sorudaki örnek iç mekanlara dokunulmaz.
Brandon Rhodes

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

Bu regex çözümlerini henüz kimse yayınlamadı.

Eşleştirme:

>>> 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

Arama ("yalnızca boşluklar" girdi durumunu farklı işlemek zorundasınız):

>>> 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'

Eğer kullanırsanız re.sub, size istenmeyen olabilir iç boşluk, kaldırabilir.


3

Boşluk içeren boşluk, sekme ve CRLF . Yani kullanabileceğimiz zarif ve tek astarlı bir dize işlevi çevirmektir .

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

VEYA ayrıntılı olmak istiyorsanız

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

3

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

Bu, tüm istenmeyen boşlukları ve yeni satır karakterlerini kaldıracaktır. Umarım bu yardım

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

Bunun sonucu:

'a b \ nc' , 'ab c' olarak değiştirilecek


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

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

çıktı:

please_remove_all_whitespaces


Cevaba Le Droid'in yorumu ekleniyor. Bir boşlukla ayırmak için:

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

çıktı:

lütfen tüm ekstra boşlukları kaldırın


1
Basit ve verimli. "" .Join (... kelimelerini boşlukla ayrılmış halde tutmak için kullanılabilir.
Le Droid

1

Python 3 kullanıyorsanız: Baskı bildiriminizde sep = "" ile bitirin. Bu tüm alanları ayıracaktır.

MİSAL:

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

Bu yazdıracak: Patatesleri seviyorum.

Yerine: Patatesleri seviyorum.

Sizin durumunuzda, \ t yolundan gitmeye çalışacağınız için sep = "\ t"


1

Burada çeşitli anlayış dereceleri ile birkaç çözüm inceledikten sonra, dize virgülle ayrılmışsa ne yapacağımı merak ettim ...

sorun

İletişim bilgilerini bir csv işlemeye çalışırken, bu sorunun bir çözümüne ihtiyacım vardı: yabancı boşlukları ve bazı önemsiz öğeleri kırpın, ancak sondaki virgülleri ve dahili boşlukları koruyun. Kişiler üzerinde notlar içeren bir alanla çalışarak, iyi şeyleri bırakarak çöpü kaldırmak istedim. Tüm noktalama işaretlerini ve samanları kırparak, daha sonra yeniden oluşturmak istemediğim için bileşik belirteçler arasındaki boşluğu kaybetmek istemedim.

normal ifade ve desenler: [\s_]+?\W+

Örüntü, boşluk karakterlerinin tekli örneklerini ve 1'den sınırsız sayıda alt çizgiye ('_') tembel olarak (mümkün olduğunca az sayıda karakter) 1'den sınırsız sayıdaya kadar [\s_]+?gelen sözcük olmayan karakterlerden önce gelir. bununla zaman: \W+(eşdeğerdir [^a-zA-Z0-9_]). Özellikle, boşluk alanlarını bulur: boş karakterler (\ 0), sekmeler (\ t), yeni satırlar (\ n), ileri besleme (\ f), satır başı (\ r).

Bunun avantajını iki misli olarak görüyorum:

  1. bir arada tutmak isteyebileceğiniz tüm kelimeler / jetonlar arasındaki boşlukları kaldırmaması;

  2. Python'un yerleşik dize yöntemi dize strip()içinde ele alınmaz, sadece sol ve sağ uçlarla ilgilidir ve varsayılan arg null karakterdir (aşağıdaki örneğe bakın: metinde birkaç yeni satır vardır strip()ve normal ifade deseni yapılırken hepsini kaldırmaz) .text.strip(' \n\t\r')

Bu OP sorusunun ötesine geçer, ancak sanırım yaptığım gibi metin verilerinde tuhaf, patolojik örneklere sahip olabileceğimiz birçok durum olduğunu düşünüyorum (bazı karakterler kaçış karakterlerinin nasıl ortaya çıktığını). Dahası, liste benzeri dizelerde, sınırlayıcı iki boşluk karakteri veya '-,' veya '-, ,,,' gibi bazı sözcük olmayan karakterleri ayırmadığı sürece sınırlayıcıyı ortadan kaldırmak istemiyoruz.

Not: CSV'nin sınırlayıcısından bahsetmiyorum. Yalnızca CSV içindeki verilerin liste benzeri olduğu örneklerdir, yani alt dizelerin cs dizesidir.

Tam açıklama: Metni yalnızca yaklaşık bir aydır manipüle ediyorum ve sadece son iki haftayı düzenliyorum, bu yüzden eksik olduğum bazı nüanslar olduğundan eminim. Bununla birlikte, daha küçük dize koleksiyonları için (benimki 12.000 satır ve 40 tek sütunluk bir veri çerçevesinde), yabancı karakterlerin kaldırılması için bir geçişten sonra son bir adım olarak, bu, özellikle de bazı ek boşluklar eklerseniz, kelime olmayan bir karakterle birleştirilen metni ayırmak ister, ancak daha önce bulunmayan boşluk eklemek istemezsiniz.

Bir örnek:

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)

Bu çıktılar:

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'

Böylece şerit her seferinde bir boşluk kaldırır. Yani OPs durumunda, strip()gayet iyi. ancak işler daha karmaşık hale gelirse, normal ifadeler ve benzer bir desen daha genel ayarlar için önemli olabilir.

eylemde görmek


0

çevirmeyi dene

>>> 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

Beyaz alanı dizenin sadece başından ve sonundan kesmek istiyorsanız, şöyle bir şey yapabilirsiniz:

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

Bu, Qt'nin QString :: trimmed () yöntemine çok benzer şekilde çalışır, çünkü dahili boşlukları yalnız bırakırken önde gelen ve arkadaki boşlukları kaldırır.

Eğer QT'ın QString gibi bir şey :: basitleştirilmiş () lider ve sonlarındaki boşluk kaldırır sadece yöntem, aynı zamanda "squishes" bir boşluk karakteri bütün ardışık iç boşluk istiyorum Ama eğer bir kombinasyonunu kullanabilirsiniz .split()ve " ".joinbu gibi:

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

Bu son örnekte, dahili boşlukların her dizisi tek bir boşlukla değiştirilirken, boşlukları dizenin başlangıcından ve sonundan keser.


-1

Genellikle aşağıdaki yöntemi kullanıyorum:

>>> 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'

Not: Bu yalnızca "\ n", "\ r" ve "\ t" öğelerini kaldırmak içindir. Fazladan boşluk bırakmaz.


-2

beyazları dizenin ortasından kaldırmak için

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

çıktı:

ATGCGACACGATCGACC

1
Bu sorular Javascript veya perl değil, python ile ilgilidir
phuclv

-17

Bu, bir dizenin başından ve sonundan tüm boşlukları ve yeni satırları kaldıracaktır:

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

8
s.strip()Tam olarak bunu yaparken neden normal ifadeyi kullanmalıyım ?
Ned Batchelder

1
s.strip()yalnızca başlangıçtaki beyaz alanı işler , ancak diğer istenmeyen karakterleri kaldırdıktan sonra "keşfedilen" boşlukları kullanmaz. Bunun, son liderlikten sonra boşlukları bile kaldıracağını unutmayın\n
Rafe

Birisi bu cevabı aşağı oyladı, ancak neden kusurlu olduğunu açıklamadı. Shame on you (@NedBatchelder, aşağı oy olsaydı lütfen sorunuzu açıkladığım gibi tersine dönün ve cevabımla kırık bir şeyden bahsetmediniz)
Rafe

10
Rafe, tekrar kontrol etmek isteyebilirsiniz: s.strip()normal ifadenizle tam olarak aynı sonucu üretir.
Ned Batchelder

3
@Rafe, trim ile karıştırıyorsun. Strip gerekli işlemleri yapar.
iMitwe
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.