Làm thế nào để tôi cắt khoảng trắng?


1071

Có một hàm Python sẽ cắt khoảng trắng (khoảng trắng và tab) từ một chuỗi không?

Ví dụ: \t example string\texample string


1
Cảm ơn cho những người đứng đầu lên. Tôi đã phát hiện ra chức năng dải trước đó, nhưng dường như nó không hoạt động cho đầu vào của tôi ..
Chris

1
Tương tự như: stackoverflow.com/questions/761804/trimming-a-opes-in-python (mặc dù câu hỏi này hơi rõ ràng hơn, IMHO). Điều này cũng gần giống nhau: stackoverflow.com/questions/959215/
Kẻ

6
Các ký tự python xem xét khoảng trắng được lưu trữ trong string.whitespace.
John Fouhy

2
Theo "hàm dải", bạn có nghĩa là phương pháp dải? "Dường như nó không hoạt động cho đầu vào của tôi" Vui lòng cung cấp mã, đầu vào và đầu ra của bạn.
S.Lott

5
Bản sao có thể có của Cắt xén một chuỗi trong Python
Breno Baiardi

Câu trả lời:


1599

Khoảng trắng ở cả hai phía:

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

Khoảng trắng ở phía bên phải:

s = s.rstrip()

Khoảng trắng ở phía bên trái:

s = s.lstrip()

Như thedz chỉ ra, bạn có thể cung cấp một đối số để loại bỏ các ký tự tùy ý cho bất kỳ chức năng nào như thế này:

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

Điều này sẽ tước bất kỳ không gian, \t, \n, hoặc \rký tự từ phía bên trái tay, phía bên tay phải, hoặc cả hai bên của chuỗi.

Các ví dụ trên chỉ loại bỏ các chuỗi từ phía bên trái và bên phải của chuỗi. Nếu bạn cũng muốn xóa các ký tự khỏi giữa chuỗi, hãy thử re.sub:

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

Điều đó sẽ in ra:

astringexample

18
dải () mất trong một cuộc tranh cãi để nói với nó những gì cần đi. Hãy thử: dải ('\ t \ n \ r')
thedz

3
Kết quả cho các ví dụ sẽ khá hữu ích :)
tấn

4
Không cần phải vào danh sách các nhân vật khoảng trắng: docs.python.org/2/library/string.html#string.whitespace
jesuis

3
Ví dụ cuối cùng chính xác là sử dụng str.replace(" ",""). Bạn không cần sử dụng re, trừ khi bạn có nhiều hơn một không gian, thì ví dụ của bạn không hoạt động. []được thiết kế để đánh dấu các ký tự đơn, không cần thiết nếu bạn chỉ sử dụng \s. Sử dụng một trong hai \s+hoặc [\s]+(không cần thiết) nhưng [\s+]không thực hiện công việc, đặc biệt nếu bạn muốn thay thế nhiều không gian bằng một không gian như biến "this example" thành "this example".
Jorge E. Cardona

3
@ JorgeE.Cardona - Một điều bạn hơi sai về - \ssẽ bao gồm các tab trong khi replace(" ", "")không.
ArtOfWarfare 30/03/2017

72

trimPhương thức Python được gọi là strip:

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

5
Điều này rất dễ nhớ vì s tri p trông gần giống như tri m.
isar

22

Đối với khoảng trắng hàng đầu và dấu:

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

Mặt khác, một biểu thức chính quy hoạt động:

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

1
Bạn đã không biên dịch regex của bạn. Bạn cần phải làm điều đópat = re.compile(r'\s+')
Evan Fosmark

Bạn thường muốn sub(" ", s)không ""sau này sẽ hợp nhất các từ và bạn sẽ không còn có thể sử dụng .split(" ")để tokenize.
dùng3467349

thật tuyệt khi thấy đầu ra của các printbáo cáo
Ron Klein

19

Bạn cũng có thể sử dụng hàm rất đơn giản và cơ bản: str.replace () , hoạt động với các khoảng trắng và tab:

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

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

Đơn giản và dễ dàng.


2
Nhưng điều này, than ôi, cũng loại bỏ không gian nội thất, trong khi ví dụ trong câu hỏi ban đầu khiến không gian bên trong không bị ảnh hưởng.
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

Không ai đã đăng các giải pháp regex này.

Phù hợp:

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

Tìm kiếm (bạn phải xử lý trường hợp nhập "chỉ khoảng trắng" khác nhau):

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

Nếu bạn sử dụng re.sub, bạn có thể loại bỏ khoảng trắng bên trong, điều này có thể không mong muốn.


3

Khoảng trắng bao gồm không gian, tab và CRLF . Vì vậy, một chức năng chuỗi thanh lịch và một lớp lót chúng ta có thể sử dụng là dịch .

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

HOẶC nếu bạn muốn kỹ lưỡng

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

3

(re.sub ('+', '', (my_str.replace ('\ n', '')))). dải ()

Điều này sẽ loại bỏ tất cả các không gian không mong muốn và các ký tự dòng mới. Hy vọng điều này giúp đỡ

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

Điều này sẽ dẫn đến:

'a b \ nc' sẽ được đổi thành 'ab c'


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

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

đầu ra:

xin vui lòng_remove_all_whitespaces


Thêm bình luận của Le Droid vào câu trả lời. Để phân tách với một khoảng trắng:

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

đầu ra:

vui lòng xóa tất cả các khoảng trắng thừa


1
Đơn giản và hiệu quả. Có thể sử dụng "" .join (... để giữ các từ được phân tách bằng dấu cách.
Le Droid

1

Nếu sử dụng Python 3: Trong câu lệnh in của bạn, kết thúc bằng sep = "". Điều đó sẽ tách ra tất cả các không gian.

THÍ DỤ:

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

Điều này sẽ in: Tôi yêu khoai tây.

Thay vì: Tôi yêu khoai tây.

Trong trường hợp của bạn, vì bạn sẽ cố gắng lái \ t, hãy làm sep = "\ t"


1

Đã xem xét khá nhiều giải pháp ở đây với nhiều mức độ hiểu biết khác nhau, tôi tự hỏi phải làm gì nếu chuỗi được phân tách bằng dấu phẩy ...

vấn đề

Trong khi cố gắng xử lý một csv thông tin liên hệ, tôi cần một giải pháp cho vấn đề này: cắt khoảng trắng bên ngoài và một số rác, nhưng giữ nguyên dấu phẩy và khoảng trắng bên trong. Làm việc với một trường chứa các ghi chú trên danh bạ, tôi muốn loại bỏ rác, để lại những thứ tốt. Cắt xén tất cả các dấu chấm câu và đục, tôi không muốn mất khoảng trắng giữa các mã thông báo vì tôi không muốn xây dựng lại sau này.

regex và các mẫu: [\s_]+?\W+

Mẫu tìm kiếm các trường hợp duy nhất của bất kỳ ký tự khoảng trắng nào và dấu gạch dưới ('_') từ 1 đến số lần không giới hạn một cách lười biếng (càng ít ký tự càng tốt) [\s_]+?đi kèm trước các ký tự không phải từ xuất hiện từ 1 đến số lượng không giới hạn thời gian với điều này: \W+(tương đương với [^a-zA-Z0-9_]). Cụ thể, điều này tìm thấy các khoảng trắng: null ký tự (\ 0), tab (\ t), dòng mới (\ n), chuyển tiếp thức ăn (\ ​​f), trả về vận chuyển (\ r).

Tôi thấy lợi thế này là hai lần:

  1. rằng nó không xóa khoảng trắng giữa các từ / mã thông báo hoàn chỉnh mà bạn có thể muốn giữ lại với nhau;

  2. Phương thức chuỗi dựng sẵn của Python strip()không xử lý bên trong chuỗi, chỉ có đầu bên trái và bên phải và đối số mặc định là ký tự null (xem ví dụ bên dưới: một số dòng mới có trong văn bản và strip()không xóa tất cả trong khi mẫu regex thực hiện) .text.strip(' \n\t\r')

Điều này vượt xa câu hỏi của OP, nhưng tôi nghĩ có rất nhiều trường hợp chúng ta có thể có những trường hợp bệnh hoạn, kỳ quặc trong dữ liệu văn bản, như tôi đã làm (một số cách các ký tự thoát kết thúc trong một số văn bản). Ngoài ra, trong các chuỗi giống như danh sách, chúng tôi không muốn loại bỏ dấu phân cách trừ khi dấu phân cách tách hai ký tự khoảng trắng hoặc một số ký tự không phải từ, như '-,' hoặc '-, ,,,'.

NB: Không nói về dấu phân cách của chính CSV. Chỉ các trường hợp trong CSV có dữ liệu giống như danh sách, tức là chuỗi cs của chuỗi con.

Tiết lộ đầy đủ: Tôi mới chỉ thao túng văn bản trong khoảng một tháng và regex chỉ trong hai tuần qua, vì vậy tôi chắc chắn có một số sắc thái tôi đang thiếu. Điều đó nói rằng, đối với các bộ sưu tập chuỗi nhỏ hơn (của tôi nằm trong khung dữ liệu gồm 12.000 hàng và 40 cột lẻ), là bước cuối cùng sau khi vượt qua để loại bỏ các ký tự không liên quan, điều này hoạt động rất tốt, đặc biệt nếu bạn giới thiệu một số khoảng trắng bổ sung nơi bạn muốn tách văn bản được nối bởi một ký tự không phải từ, nhưng không muốn thêm khoảng trắng ở nơi không có từ trước.

Một ví dụ:

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)

Kết quả này:

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'

Vì vậy, dải loại bỏ một khoảng trắng tại một thời điểm. Vì vậy, trong trường hợp OP, strip()là tốt. nhưng nếu mọi thứ trở nên phức tạp hơn, regex và một mẫu tương tự có thể có giá trị đối với các cài đặt chung hơn.

nhìn thấy nó trong hành động


0

thử dịch

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

Nếu bạn muốn cắt bớt khoảng trắng ở đầu và cuối chuỗi, bạn có thể làm một cái gì đó như thế này:

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

Điều này hoạt động rất giống như phương thức QString :: trimmed () của Qt, trong đó nó loại bỏ khoảng trắng hàng đầu và dấu, trong khi chỉ để lại khoảng trắng bên trong.

Nhưng nếu bạn thích một cái gì đó giống như phương thức QString :: Simplified () của Qt, nó không chỉ loại bỏ khoảng trắng hàng đầu và dấu, mà còn "squishes" tất cả các khoảng trắng bên trong liên tiếp cho một ký tự khoảng trắng, bạn có thể sử dụng kết hợp .split()" ".join, như thế này:

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

Trong ví dụ cuối cùng này, mỗi chuỗi khoảng trắng bên trong được thay thế bằng một khoảng trắng, trong khi vẫn cắt bớt khoảng trắng ở đầu và cuối chuỗi.


-1

Nói chung, tôi đang sử dụng phương pháp sau:

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

Lưu ý: Điều này chỉ để xóa "\ n", "\ r" và "\ t" mà thôi. Nó không loại bỏ thêm không gian.


-2

để loại bỏ khoảng trắng từ giữa chuỗi

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

đầu ra:

ATGCGACACGATCGACC

1
câu hỏi này là về python, không phải Javascript hay perl
phuclv

-17

Điều này sẽ xóa tất cả khoảng trắng và dòng mới từ cả đầu và cuối của chuỗi:

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

8
Tại sao sử dụng regex khi s.strip()chính xác điều này?
Ned Batchelder

1
s.strip()chỉ xử lý khoảng trắng ban đầu , nhưng không được phát hiện "khoảng trắng" sau khi xóa các ký tự không mong muốn khác. Lưu ý rằng điều này sẽ xóa ngay cả khoảng trắng sau lần dẫn cuối cùng\n
Rafe

Một số người đã bỏ phiếu trả lời câu trả lời này nhưng không giải thích được tại sao nó không hoàn hảo. Thật xấu hổ cho bạn (@NedBatchelder nếu bạn bỏ phiếu xuống, xin vui lòng đảo ngược khi tôi giải thích câu hỏi của bạn và bạn đã không đề cập đến bất cứ điều gì thực sự bị phá vỡ với câu trả lời của tôi)
Rafe

10
Rafe, bạn có thể muốn kiểm tra lại: s.strip()tạo ra kết quả chính xác giống như biểu thức chính quy của bạn.
Ned Batchelder

3
@Rafe, bạn đang nhầm lẫn nó với trim. Dải thực hiện các hoạt động cần thiết.
iMitwe
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.