ฉันจะตัดช่องว่างได้อย่างไร


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
string.whitespaceหลามตัวอักษรพิจารณาช่องว่างจะถูกเก็บไว้ใน
John Fouhy

2
โดย "strip function" คุณหมายถึง strip method หรือไม่ "ดูเหมือนจะใช้งานไม่ได้กับอินพุตของฉัน" โปรดระบุรหัสอินพุตและเอาต์พุตของคุณ
S.Lott

5
สำเนาซ้ำที่เป็นไปได้ของการตัดแต่งสตริงใน Python
Breno Baiardi

คำตอบ:


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 () ใช้เวลาในการ arguemnt เพื่อบอกสิ่งที่จะเดินทาง ลอง: ดึง ('\ t \ n \ r')
thedz

3
ผลการค้นหาสำหรับตัวอย่างที่ควรจะเป็นประโยชน์มาก :)
ตัน

4
ไม่จำเป็นต้องแสดงรายการอักขระช่องว่าง: docs.python.org/2/library/string.html#string.whitespace
jesuis

3
str.replace(" ","")ตัวอย่างสุดท้ายคือตรงตามที่ใช้ คุณไม่จำเป็นต้องใช้reเว้นเสียแต่ว่าคุณจะมีมากกว่าหนึ่งช่องว่างตัวอย่างของคุณก็ใช้ไม่ได้ ถูกออกแบบมาเพื่อทำเครื่องหมายตัวอักษรเดียวก็ไม่จำเป็นถ้าคุณกำลังใช้เพียง[] \sใช้อย่างใดอย่างหนึ่ง\s+หรือ[\s]+(ที่ไม่จำเป็น) แต่[\s+]ไม่ได้ทำงานโดยเฉพาะอย่างยิ่งถ้าคุณต้องการที่จะเข้ามาแทนที่ช่องว่างหลายที่มีหนึ่งเดียวเช่นการเปลี่ยนเข้าสู่"this example" "this example"
Jorge E. Cardona

3
@ JorgeE.Cardona - สิ่งหนึ่งที่คุณผิดเล็กน้อยเกี่ยวกับ - \sจะรวมแท็บในขณะที่replace(" ", "")ไม่ใช้
ArtOfWarfare

72

trimวิธีการที่เรียกว่างูหลามstrip:

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

5
ซึ่งง่ายต่อการจดจำเนื่องจาก s tri p ดูเหมือนกับtri m
isar

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
คุณไม่ได้รวบรวม regex ของคุณ คุณต้องทำให้เป็นอย่างนั้นpat = re.compile(r'\s+')
Evan Fosmark

โดยทั่วไปคุณsub(" ", s)ไม่ต้องการ""รวมคำในภายหลังและคุณจะไม่สามารถใช้โท.split(" ")เค็นได้อีก
user3467349

มันจะดีที่จะเห็นผลลัพธ์ของprintงบ
Ron Klein

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

ยังไม่มีใครประกาศโซลูชัน regex เหล่านี้

จับคู่:

>>> 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', '')))). แถบ ()

สิ่งนี้จะลบช่องว่างและอักขระขึ้นบรรทัดใหม่ทั้งหมด หวังว่าความช่วยเหลือนี้

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="")

สิ่งนี้จะพิมพ์: ฉันรักมันฝรั่ง

แทนที่จะเป็น: ฉันรักมันฝรั่ง

ในกรณีของคุณเนื่องจากคุณจะพยายามขับรถ \ t ให้ทำ sep = "\ t"


1

เมื่อดูที่วิธีแก้ปัญหาหลายอย่างที่นี่ด้วยความเข้าใจที่หลากหลายฉันสงสัยว่าจะทำอย่างไรถ้าแยกสตริงด้วยเครื่องหมายจุลภาค ...

ปัญหา

ในขณะที่พยายามประมวลผลข้อมูลการติดต่อ csv ฉันต้องการวิธีแก้ปัญหานี้: ตัดช่องว่างภายนอกและขยะบางส่วนออก แต่เก็บเครื่องหมายจุลภาคต่อท้ายและช่องว่างภายใน การทำงานกับเขตข้อมูลที่มีบันทึกย่อของผู้ติดต่อฉันต้องการลบขยะทิ้งสิ่งที่ดี การตัดเครื่องหมายวรรคตอนและแกลบออกทั้งหมดฉันไม่ต้องการสูญเสียช่องว่างระหว่างโทเค็นผสมเนื่องจากฉันไม่ต้องการสร้างใหม่ในภายหลัง

regex และรูปแบบ: [\s_]+?\W+

รูปแบบค้นหาอินสแตนซ์เดียวของอักขระช่องว่างและขีดล่าง ('_') จาก 1 ถึงจำนวนไม่ จำกัด ครั้งที่ขี้เกียจ (น้อยที่สุดเท่าที่เป็นไปได้) โดย[\s_]+?ที่มาก่อนอักขระที่ไม่ใช่คำที่เกิดขึ้นจาก 1 ถึงไม่ จำกัด จำนวน เวลากับสิ่งนี้: \W+(เทียบเท่า[^a-zA-Z0-9_]) สิ่งนี้จะค้นหาแถบพื้นที่ว่าง: อักขระ null (\ 0), แท็บ (\ t), บรรทัดใหม่ (\ n), ฟีดไปข้างหน้า (\ f), การคืนค่าขนส่ง (\ r)

ฉันเห็นความได้เปรียบนี้เป็นสองเท่า:

  1. จะไม่ลบช่องว่างระหว่างคำ / โทเค็นที่สมบูรณ์ซึ่งคุณอาจต้องการเก็บไว้ด้วยกัน;

  2. Python สร้างขึ้นในวิธีการสตริงstrip()ไม่จัดการภายในสตริงเพียงแค่ซ้ายและขวาสิ้นสุดและหาเรื่องเริ่มต้นเป็นตัวละครโมฆะ (ดูตัวอย่างด้านล่าง: ขึ้นบรรทัดใหม่หลายข้อความและstrip()ไม่ได้ลบออกทั้งหมดในขณะที่รูปแบบ regex ไม่) .text.strip(' \n\t\r')

สิ่งนี้นอกเหนือไปจากคำถาม OPs แต่ฉันคิดว่ามีหลายกรณีที่เราอาจมีกรณีทางพยาธิวิทยาที่แปลกประหลาดภายในข้อมูลข้อความเช่นเดียวกับฉัน (บางวิธีอักขระตัวละครจบลงในข้อความบางส่วน) ยิ่งไปกว่านั้นในรายการที่คล้ายสตริงเราไม่ต้องการกำจัดตัวคั่นเว้นแต่ตัวคั่นจะแยกอักขระช่องว่างสองตัวหรืออักขระที่ไม่ใช่คำเช่น '-' หรือ '-, ,,,'

หมายเหตุ: ไม่ได้พูดถึงตัวคั่นของ CSV เอง มีเพียงอินสแตนซ์ภายใน CSV ที่มีข้อมูลคล้ายรายการนั่นคือสตริง cs ของสตริงย่อย

การเปิดเผยอย่างเต็มรูปแบบ: ฉันเพิ่งจัดการข้อความเป็นเวลาประมาณหนึ่งเดือนและ regex เพียงสองสัปดาห์ที่ผ่านมาดังนั้นฉันจึงมั่นใจว่ามีความแตกต่างเล็กน้อยที่ฉันขาดไป ที่กล่าวว่าสำหรับคอลเลกชันเล็ก ๆ ของสตริง (ของฉันอยู่ใน dataframe ของ 12,000 แถวและ 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'

ดังนั้นแถบจะลบช่องว่างออกหนึ่งช่องในเวลาเดียวกัน ดังนั้นในกรณี OPs strip()เป็นเรื่องปกติ แต่ถ้าสิ่งต่าง ๆ มีความซับซ้อนมากขึ้น regex และรูปแบบที่คล้ายกันอาจมีค่าสำหรับการตั้งค่าทั่วไปเพิ่มเติม

เห็นมันในการกระทำ


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

วิธีนี้ใช้ได้ผลเหมือนกับวิธี QString :: trimmed () ของ Qt ซึ่งจะลบช่องว่างชั้นนำและส่วนท้ายในขณะที่ปล่อยให้ช่องว่างภายในอยู่คนเดียว

แต่ถ้าคุณต้องการวิธี QString :: simplified () ของ Qt ซึ่งไม่เพียง แต่จะลบช่องว่างชั้นนำและตามหลัง แต่ยัง "squishes" ช่องว่างภายในที่ต่อเนื่องกันทั้งหมดไปยังอักขระช่องว่างหนึ่งคุณสามารถใช้การรวมกันของ.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
คำถามนี้เกี่ยวกับหลามไม่ใช่ Javascript หรือ perl
phuclv

-17

สิ่งนี้จะลบช่องว่างและบรรทัดใหม่ทั้งหมดออกจากจุดเริ่มต้นและจุดสิ้นสุดของสตริง:

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

8
ทำไมต้องใช้ regex เมื่อs.strip()ทำสิ่งนี้ทุกประการ
Ned Batchelder

1
s.strip()จัดการกับพื้นที่สีขาวเริ่มต้นเท่านั้น แต่ไม่ใช่ช่องว่าง "ค้นพบ" หลังจากลบอักขระที่ไม่ต้องการอื่น ๆ โปรดทราบว่าสิ่งนี้จะลบแม้กระทั่งช่องว่างหลังจากนำหน้าสุดท้าย\n
Rafe

บางคนลงคะแนนให้กับคำตอบนี้ แต่ไม่ได้อธิบายว่าทำไมจึงมีข้อบกพร่อง ความอับอายกับคุณ (@NedBatchelder ถ้าลงคะแนนที่ถูกคุณกรุณาย้อนกลับเป็นฉันอธิบายคำถามของคุณและคุณไม่ได้พูดถึงอะไรเสียจริงกับคำตอบของฉัน)
ราเฟล

10
Rafe คุณอาจต้องการตรวจสอบอีกครั้ง: s.strip()ให้ผลลัพธ์ที่ตรงกับ regex ของคุณอย่างแม่นยำ
Ned Batchelder

3
@Rafe คุณสับสนกับการตัดแต่ง สตริปทำการดำเนินการที่จำเป็น
iMitwe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.