2009-12-14 56 views
46

string.whitespace Python là rất tốt:Hủy bỏ khoảng trắng trong Python sử dụng string.whitespace

>>> string.whitespace 
'\t\n\x0b\x0c\r ' 

Làm thế nào để sử dụng này với một chuỗi mà không cần đến nhập thủ '\ t | \ n | ... vv cho regex?

Ví dụ: nó sẽ có thể biến: "Xin vui lòng \ không làm tổn thương \ x0b tôi".

vào

"Xin đừng làm tổn thương tôi".

Tôi có thể muốn giữ các khoảng trống đơn, nhưng thật dễ dàng để chỉ cần đi chuỗi.whitespace [: - 1] Tôi giả sử.

Trả lời

142

Có một phím tắt đặc biệt hợp cụ thể đối với trường hợp sử dụng chính xác này!

Nếu bạn gọi str.split mà không có đối số, nó chia tách trên các khoảng trắng thay vì các ký tự đơn. Vì vậy:

>>> ' '.join("Please \n don't \t hurt \x0b me.".split()) 
"Please don't hurt me." 
+5

Điều đó cực kỳ tốt hơn giải pháp của tôi. Tôi cũng hy vọng sẽ trở thành bất tử một ngày nào đó. –

+0

Chà. Thật là tuyệt vời. Hoàn hảo cho những gì tôi đang làm, vì chúng là những chuỗi nhỏ. Tôi tự hỏi làm thế nào điều này sẽ thực hiện trên datasets lớn mặc dù? Nó sẽ là tuyệt vời nếu ai biết làm thế nào nó hoạt động intrinsicly :) – Alex

+0

cảm ơn, không biết về việc sử dụng không có đối số cho chạy của khoảng trắng. Khổng lồ!! – MattoTodd

1

một điểm khởi đầu .. (mặc dù nó không phải là ngắn hơn bằng tay lắp ráp xiếc khoảng trắng) ..

>>> from string import whitespace as ws 
>>> import re 

>>> p = re.compile('(%s)' % ('|'.join([c for c in ws]))) 
>>> s = "Please \n don't \t hurt \x0b me." 

>>> p.sub('', s) 
"Pleasedon'thurtme." 

Hoặc nếu bạn muốn giảm bớt khoảng trắng đến tối đa là một:

>>> p1 = re.compile('(%s)' % ('|'.join([c for c in ws if not c == ' ']))) 
>>> p2 = re.compile(' +') 
>>> s = "Please \n don't \t hurt \x0b me." 

>>> p2.sub(' ', p1.sub('', s)) 
"Please don't hurt me." 

Cách thứ ba, gọn hơn:

>>> import string 

>>> s = "Please \n don't \t hurt \x0b me." 
>>> s.translate(None, string.whitespace[]) 
"Pleasedon'thurtme." 

>>> s.translate(None, string.whitespace[:5]) 
"Please don't hurt me." 

>>> ' '.join(s.translate(None, string.whitespace[:5]).split()) 
"Please don't hurt me." 
+0

Tôi ban đầu có điều này làm câu trả lời đầu tiên; đó là một giải pháp tốt đẹp và sử dụng tốt đơn giản python :) – Alex

2

Bạn có thể sử dụng phương pháp dịch

import string 

s = "Please \n don't \t hurt \x0b me." 
s = s.translate(None, string.whitespace[:-1]) # python 2.6 and up 
s = s.translate(string.maketrans('',''), string.whitespace[:-1]) # python 2.5, dunno further down 
>>> s 
"Please don't hurt me." 

Và sau đó loại bỏ trùng lặp khoảng trắng

s.replace(' ', ' ') 
>>> s 
"Please don't hurt me." 
+0

Dường như không hoạt động ... sẽ là tốt đẹp nếu nó đã làm mặc dù! – Alex

+0

xem chỉnh sửa. Ngoài ra, bạn đang sử dụng phiên bản python nào? bạn cần 2.6 cho đối số None để làm việc. –

+0

Vâng, tôi đang sử dụng 2,5 ... là có một thay thế cho Không? Nếu không, tôi sẽ phải sử dụng câu trả lời khác ... – Alex

13

Có gì sai với lớp nhân vật \s?

>>> import re 

>>> pattern = re.compile(r'\s+') 
>>> re.sub(pattern, ' ', "Please \n don't \t hurt \x0b me.") 
"Please don't hurt me." 
+0

Không có gì, giải pháp tốt. Tôi nghĩ tùy chọn .join/split khá gọn gàng, bạn có nghĩ vậy không? :) – Alex

+1

Thật vậy. Thực tế, 'timeit' hiển thị tham gia/chia nhỏ thành 6 lần nhanh hơn re.sub() cho chuỗi đã cho của bạn. – Imran

+0

Tôi giả sử một khi được biên dịch và 'phụ' được sử dụng lại nhiều lần, điều này có thể nhanh quá –

9

Hãy làm cho một số giả định hợp lý:

(1) Bạn thực sự muốn thay thế bất kỳ chạy của nhân vật khoảng trắng với một không gian duy nhất (một hoạt động có chiều dài 1 hoặc cao hơn).

(2) Bạn muốn có cùng một mã để làm việc với những thay đổi tối thiểu trong Python 2.X với các đối tượng unicode.

(3) Bạn không muốn mã của bạn để đảm nhận những điều không được bảo đảm trong các tài liệu

(4) Bạn muốn cùng mã để làm việc với thay đổi tối thiểu với các đối tượng Python 3.x str.

Câu trả lời hiện đang được chọn có những vấn đề này:

(a) thay đổi " " * 3-" " * 2 tức là nó loại bỏ không gian trùng lặp nhưng không gấp ba, gấp bốn, vv không gian.[Không yêu cầu 1]

(b) thay đổi "foo\tbar\tzot" để "foobarzot" [thất bại yêu cầu 1]

(c) khi cho ăn một đối tượng unicode, được TypeError: translate() takes exactly one argument (2 given) [thất bại yêu cầu 2]

(d) sử dụng string.whitespace[:-1] [yêu cầu thất bại 3; thứ tự của các ký tự trong string.whitespace không được đảm bảo]

(e) sử dụng string.whitespace[:-1] [yêu cầu không thành công 4; trong Python 2.X, string.whitespace là '\t\n\x0b\x0c\r '; trong Python 3.X, nó là '\ t \ n \ r \ x0b \ x0c']

Câu trả lời " ".join(s.split()) và câu trả lời re.sub(r"\s+", " ", s) không có những vấn đề này.

+0

Xin chào, bạn đã nêu ra một số điểm tuyệt vời. Đối với tôi, '' .join (s.split()) hoạt động trên bài kiểm tra "foo \ tbar \ tzot"! Ý tôi là, câu trả lời ban đầu có hiệu quả với tôi, nhưng đó chỉ là vì tôi không mong đợi những sợi dây kỳ lạ như vậy. Tuy nhiên một cái gì đó mà đề với điều này sẽ là tuyệt vời. Tôi chỉ thử nghiệm phụ với "foo \ tbar \ tzot" và nó hoạt động ... vì vậy tôi đoán tôi chỉ chọn phiên bản '' .join (s.split()) do tính đơn giản và có thể hoạt động mà không cần nhập lại mô-đun. Ngoài ra bộ dữ liệu của tôi là nhỏ, vì vậy tôi không lo lắng về vấn đề hiệu suất, nếu có bất kỳ. – Alex

Các vấn đề liên quan