2016-04-30 17 views
10

Tôi có một tập tin .txt (cạo như trước khi định dạng văn bản từ một trang web) nơi dữ liệu trông như thế này:Loại bỏ khoảng trắng từ txt với python

B, NICKOLAS      CT144531X  D1026 JUDGE ANNIE WHITE JOHNSON 
ANDREWS VS BALL     JA-15-0050  D0015 JUDGE EDWARD A ROBERTS   

Tôi muốn loại bỏ tất cả dấu cách thêm (chúng thực sự khác nhau về số lượng không gian, không phải tab) ở giữa các cột. Tôi cũng muốn sau đó muốn thay thế nó với một số delimiter (tab hoặc ống kể từ khi có dấu phẩy trong dữ liệu), như vậy:

ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS 

Nhìn xung quanh và phát hiện ra rằng lựa chọn tốt nhất đang sử dụng regex hoặc shlex chia. Hai kịch bản tương tự:

+1

Luôn có nhiều khoảng trống giữa các cột dữ liệu? –

+0

@ cricket_007 yep, luôn có nhiều hơn một không gian – aysha

+0

Bạn không nên sử dụng regex, vì dữ liệu có thể có 2 hoặc nhiều khoảng trống trong một cột. Dữ liệu ở định dạng bảng văn bản, cột sp phải được xác định bởi vị trí của một ký tự trên mỗi dòng. –

Trả lời

5
s = """B, NICKOLAS      CT144531X  D1026 JUDGE ANNIE WHITE JOHNSON 
ANDREWS VS BALL     JA-15-0050  D0015 JUDGE EDWARD A ROBERTS 
""" 

# Update 
re.sub(r"(\S)\ {2,}(\S)(\n?)", r"\1|\2\3", s) 
In [71]: print re.sub(r"(\S)\ {2,}(\S)(\n?)", r"\1|\2\3", s) 
B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON 
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS 
+0

Nó nối thêm một đường ống ở cuối. –

+0

Cập nhật, bây giờ kết quả rõ ràng – Janom

+0

Hoàn hảo! Sạch sẽ và đơn giản, cộng với nó thêm ngắt dòng độc đáo. – aysha

3

Xét có ít nhất hai không gian tách các cột, bạn có thể sử dụng này:

lines = [ 
'B, NICKOLAS      CT144531X  D1026 JUDGE ANNIE WHITE JOHNSON ', 
'ANDREWS VS BALL     JA-15-0050  D0015 JUDGE EDWARD A ROBERTS  ' 
] 

for line in lines: 
    parts = [] 
    for part in line.split(' '): 
     part = part.strip() 
     if part: # checking if stripped part is a non-empty string 
      parts.append(part) 
    print('|'.join(parts)) 

Output cho đầu vào của bạn:

B, NICKOLAS|CT144531X|D1026|JUDGE ANNIE WHITE JOHNSON 
ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS 
+1

Bạn đã thử nghiệm trước khi đăng câu trả lời? –

+0

Làm thế nào điều này có thể cho 'ANDREWS VS BALL | JA-15-0050 | D0015 | JUDGE EDWARD A ROBERTS'? –

+0

chăm sóc để giải thích các downvote? @PeterWood Mã được chỉnh sửa cung cấp cho đầu ra yêu cầu. –

6

gì về điều này?

your_string ='ANDREWS VS BALL     JA-15-0050  D0015 JUDGE EDWARD A ROBERTS' 
print re.sub(r'\s{2,}','|',your_string.strip()) 

Output:

ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS 

Expanation:

Tôi đã sử dụng re.sub() mà mất 3 tham số, một mô hình, một chuỗi bạn muốn thay thế bằng và chuỗi bạn muốn làm việc trên .

Điều tôi đã làm là lấy ít nhất hai không gian cùng nhau, tôi đã thay thế chúng bằng một | và áp dụng nó trên chuỗi của bạn.

7

Bạn có thể áp dụng regex '\s{2,}' (hai hoặc nhiều ký tự khoảng trống) cho mỗi dòng và thay thế các kết quả phù hợp bằng một ký tự '|'.

>>> import re 
>>> line = 'ANDREWS VS BALL     JA-15-0050  D0015 JUDGE EDWARD A ROBERTS  ' 
>>> re.sub('\s{2,}', '|', line.strip()) 
'ANDREWS VS BALL|JA-15-0050|D0015|JUDGE EDWARD A ROBERTS' 

Tước bất kỳ hàng đầu và dấu khoảng trắng từ dòng trước khi áp dụng re.sub đảm bảo rằng bạn sẽ không nhận '|' nhân vật lúc bắt đầu và kết thúc của dòng.

mã thực tế của bạn sẽ trông giống như thế này:

import re 
with open(filename) as f: 
    for line in f: 
     subbed = re.sub('\s{2,}', '|', line.strip()) 
     # do something here 
+0

Cảm ơn bạn, được giải thích rất tốt. Chỉ cần thêm một hàm linebreak. – aysha

3

Dường như dữ liệu của bạn trong một định dạng "text-bàn".

Tôi khuyên bạn nên sử dụng hàng đầu tiên để tìm ra điểm bắt đầu và độ dài của mỗi cột (bằng tay hoặc viết kịch bản với regex để xác định các cột có khả năng), sau đó viết kịch bản để lặp lại các hàng của tệp, cắt hàng thành các đoạn cột và áp dụng dải cho từng phân đoạn.

Nếu bạn sử dụng regex, bạn phải theo dõi số lượng cột và báo lỗi nếu có hàng nhất định nhiều hơn số cột dự kiến ​​(hoặc số khác với số cột còn lại). Việc chia tách trên hai hoặc nhiều không gian sẽ phá vỡ nếu giá trị của một cột có hai hoặc nhiều khoảng trống, không chỉ hoàn toàn có thể, mà còn có khả năng. Các bảng văn bản như thế này không được thiết kế để tách ra trên một regex, chúng được thiết kế để chia thành các vị trí chỉ mục cột.

Về mặt lưu dữ liệu, bạn có thể sử dụng mô-đun csv để ghi/đọc vào tệp csv. Điều đó sẽ cho phép bạn xử lý trích dẫn và thoát các ký tự tốt hơn so với chỉ định dấu phân cách. Nếu một trong các cột của bạn có ký tự | làm giá trị, trừ khi bạn mã hóa dữ liệu bằng chiến lược xử lý các lần thoát hoặc các chữ được trích dẫn, đầu ra của bạn sẽ bị ngắt khi đọc.

Phân tích văn bản trên sẽ giống như thế này (i lồng một hiểu danh sách với dấu ngoặc thay vì định dạng truyền thống vì vậy nó dễ dàng hơn để hiểu):

cols = ((0,34), 
     (34, 50), 
     (50, 59), 
     (59, None), 
     ) 
for line in lines: 
    cleaned = [i.strip() for i in [line[s:e] for (s, e) in cols]] 
    print cleaned 

sau đó bạn có thể viết nó với một cái gì đó như:

import csv 
with open('output.csv', 'wb') as csvfile: 
    spamwriter = csv.writer(csvfile, delimiter='|', 
          quotechar='"', quoting=csv.QUOTE_MINIMAL) 
    for line in lines: 
     spamwriter.writerow([line[col_start:col_end].strip() 
          for (col_start, col_end) in cols 
          ]) 
Các vấn đề liên quan