簡體   English   中英

循環播放.csv文件並刪除所有非ascii字符串

[英]Looping over .csv file and removing any non-ascii strings

我有一個.csv文件,其中包含大量電子郵件,每個電子郵件都位於單獨的一行中。 我正在嘗試刪除所有包含非ASCII字符的電子郵件。 我正在嘗試的是:

def is_ascii(s):
    return all(ord(c) < 128 for c in s)


if __name__ == "__main__":

    with open('emails.csv') as csv_file:
        for line in csv_file:
            if(is_ascii(line)):
                with open('result.csv', 'a') as output_file:
                    output_file.write(line)

它一直給我一個錯誤:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83 in position 5012: invalid start byte

問題是您不知道非ASCII電子郵件的編碼是什么,因此您只想跳過它們。

但是您的代碼嘗試使用默認編碼對它們進行解碼, 然后決定是否跳過它們。 這就是在文本模式下打開文件的含義,如下所示:

with open('emails.csv') as csv_file:
    for line in csv_file:

由於該默認編碼為UTF-8,因此一旦您遇到其他與UTF-8不兼容的字符集編碼的內容,就會收到錯誤消息。


將其更改為最簡單的方法是以二進制模式打開文件。 然后,您只能解碼您決定保留的行:

with open('emails.csv', 'rb') as csv_file:
    for line in csv_file:
        if(is_ascii(line)):
            line = line.decode('ascii')
            with open('result.csv', 'a') as output_file:
                output_file.write(line)

…或通過以二進制模式打開輸出文件來完全保留字節:

with open('emails.csv', 'rb') as csv_file:
    for line in csv_file:
        if(is_ascii(line)):
            with open('result.csv', 'ab') as output_file:
                output_file.write(line)

無論哪種方式,您都必須更改isascii函數,因為bytes是0到255之間的整數序列,而不是字符序列,因此您不能(也不需要)調用ord

def is_ascii(s):
    return all(c < 128 for c in s)

存在潛在的問題。 我認為您會沒事的,但是您應該仔細考慮一下(並測試您需要測試的任何內容)。 文本模式文件對象自動處理非Unix換行符,而二進制模式文件則不能。

如果您以某種方式擁有上個世紀的經典Mac(OS X之前的版本)文件並以\\r結尾,則您的代碼將無法工作。 \\r根本不會被視為換行符,因此整個文件看起來像是一行大行。 如果您不希望有任何此類文件,則不必擔心。

但是,如果您擁有的唯一非Unix文件是Windows(或DOS),並帶有\\r\\n ,那就可以了。 \\r將被視為行的一部分,而不是換行的一部分,但這與您的代碼無關緊要( ord('\\r') < 128 ,並且除此之外,您要做的就是編寫整行的字節數),因此一切正常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM