[py052] 通訊錄vcf與csv互轉(zhuǎn)

Coding is better than boring.
與其無(wú)聊倒不如寫(xiě)點(diǎn)東西,或許會(huì)少點(diǎn)辜負(fù)時(shí)光。
                  ---Mon,Dec 2,2019 Andy

前言:

有時(shí)候需要將vcf和csv互轉(zhuǎn)逾雄,但眾里尋他千百度,始終找不到一個(gè)通用且便捷的轉(zhuǎn)換方式腻脏。所以自己寫(xiě)一個(gè)吧鸦泳!自己以后用方便,剛好需要用的朋友遇到也方便永品。
下面來(lái)一起看看要怎么弄做鹰。

首先、兩種文件的格式有什么區(qū)別鼎姐?


1.一句話說(shuō)完钾麸「瘢“csv以逗號(hào)分隔,vcf有一堆東西饭尝,看著好復(fù)雜肯腕。”
2.csv可以excel打開(kāi)直接編輯钥平。
3.vcf的格式也是很清晰的实撒,如圖。

思路:越野越好

1.vcf轉(zhuǎn)csv,把起始標(biāo)志涉瘾、版本等全部去掉知态。
2.csv轉(zhuǎn)vcf,把那一堆加上。

廢話少說(shuō)立叛,上代碼

"""
@title:通訊錄vcf與csv互轉(zhuǎn)
@filename:vcf22csv_ok.py
"""
import os
import quopri
import re


def get_fpath_fname_fextension(file):
    """返回文件路徑负敏、文件名、拓展名"""
    (fpath, temp_fname) = os.path.split(file)
    (fname, fextension) = os.path.splitext(temp_fname)
    return fpath, fname, fextension


def vcf2csv(vcf_filename):
    """vcf格式文件轉(zhuǎn)換為csv格式文件"""
    # 1.讀取vcf文件
    with open(vcf_filename, 'r', encoding='utf-8') as f:
        try:
            ftext = f.read()
        finally:
            f.close()
    # 2.正則替換清洗數(shù)據(jù)
    re_dic = {
        r"(EMAIL;)(.*)(\n)": "",
        r"(ADR;)(.*)(\n)": "",
        r"(ORG;)(.*)(\n)": "",
        r"(NOTE:)(.*)(\n)": "",
        r"(\n)(VERSION:2.1)": "",
        r"\nEND:VCARD\nBEGIN:VCARD": "",
        r"\nEND:VCARD": "",
        r"BEGIN:VCARD\n": "",
        r"(;;;)([\s\S]*?)(TEL;CELL:)": ",",
        r"N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:": "",
        r"(\nTEL;)(.*?)(:)": ",",
        r"N:;": "",
        r";": "",
        r" ": "",
        r"=\n": ""
    }
    for re_rule, replace_str in re_dic.items():
        p1 = re.compile(re_rule)
        ftext = p1.sub(replace_str, ftext)
    # 3.解碼quopri編碼
    ftext = quopri.decodestring(ftext).decode('utf-8', "ignore").replace(" ", "")
    ftext = "".join([s for s in ftext.splitlines(True) if s.strip()])
    # 4.保存cvs文件
    csv_str = f'姓名,手機(jī)\n{ftext}'
    fname = get_fpath_fname_fextension(vcf_filename)
    with open(f'{fname[0]}{fname[1]}.csv', "w", encoding="utf-8") as f:
        try:
            f.write(csv_str)
        finally:
            f.close()


def csv2vcf(csv_filename):
    """csv格式文件轉(zhuǎn)換為vcf格式文件"""
    # 1.讀取csv文件
    with open(csv_filename, 'r', encoding='utf-8') as f:
        ftext_list = f.readlines()
        f.close()
    # 2.將cvs轉(zhuǎn)換為vcf格式
    vcards = ''
    for line in ftext_list[1:]:
        tel_numbers = ''
        name_tel_list = line.strip().split(',')
        if name_tel_list[0]:
            tel_name = name_tel_list[0]  # 姓名
            for tel in name_tel_list[1:]:  # 電話
                tel_numbers += f'TEL;CELL:{tel}\n'
            vcard = f'BEGIN:VCARD\nN:{tel_name}\n{tel_numbers}END:VCARD\n'
            vcards += vcard
    # 3.保存轉(zhuǎn)換后的vcf格式文件
    fname = get_fpath_fname_fextension(csv_filename)
    with open(f'{fname[0]}{fname[1]}.vcf', "w", encoding="utf-8") as f:
        try:
            f.write(vcards)
        finally:
            f.close()


def vcf22csv(file):
    if not os.path.isfile(file):
        print("文件不存在")
    else:
        a = get_fpath_fname_fextension(file)[2]
        if a == ".csv":
            csv2vcf(file)
            print("此文件為csv文件,已生成vcf文件")
        elif a == ".vcf":
            vcf2csv(file)
            print("此文件為vcf文件,已生成csv文件")
        else:
            print("請(qǐng)選擇正確的csv文件或者vsf文件")


if __name__ == "__main__":
    filename = "vcards.csv"
    vcf22csv(filename)
    pass

GUI版

"""
@title:通訊錄vcf與csv互轉(zhuǎn)
@filename:vcf22csv_gui_ok.py
"""
import os
import quopri
import re
import tkinter as tk
import tkinter.filedialog as tk_file
import tkinter.messagebox as msg


def get_fpath_fname_fextension(file):
    """返回文件路徑秘蛇、文件名其做、拓展名"""
    (fpath, temp_fname) = os.path.split(file)
    (fname, fextension) = os.path.splitext(temp_fname)
    return fpath, fname, fextension


def vcf2csv(vcf_filename):
    """vcf格式文件轉(zhuǎn)換為csv格式文件"""
    # 1.讀取vcf文件
    with open(vcf_filename, 'r', encoding='utf-8') as f:
        try:
            ftext = f.read()
        finally:
            f.close()
    # 2.正則替換清洗數(shù)據(jù)
    re_dic = {
        r"(EMAIL;)(.*)(\n)": "",
        r"(ADR;)(.*)(\n)": "",
        r"(ORG;)(.*)(\n)": "",
        r"(NOTE:)(.*)(\n)": "",
        r"(\n)(VERSION:2.1)": "",
        r"\nEND:VCARD\nBEGIN:VCARD": "",
        r"\nEND:VCARD": "",
        r"BEGIN:VCARD\n": "",
        r"(;;;)([\s\S]*?)(TEL;CELL:)": ",",
        r"N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:": "",
        r"(\nTEL;)(.*?)(:)": ",",
        r"N:;": "",
        r";": "",
        r" ": "",
        r"=\n": ""
    }
    for re_rule, replace_str in re_dic.items():
        p1 = re.compile(re_rule)
        ftext = p1.sub(replace_str, ftext)
    # 3.解碼quopri編碼
    ftext = quopri.decodestring(ftext).decode('utf-8', "ignore").replace(" ", "")
    ftext = "".join([s for s in ftext.splitlines(True) if s.strip()])
    # 4.保存cvs文件
    csv_str = f'姓名,手機(jī)\n{ftext}'
    fname = get_fpath_fname_fextension(vcf_filename)
    with open(f'{fname[0]}/{fname[1]}.csv', "w", encoding="utf-8") as f:
        try:
            f.write(csv_str)
        finally:
            f.close()


def csv2vcf(csv_filename):
    """csv格式文件轉(zhuǎn)換為vcf格式文件"""
    # 1.讀取csv文件
    with open(csv_filename, 'r', encoding='utf-8') as f:
        ftext_list = f.readlines()
        f.close()
    # 2.將cvs轉(zhuǎn)換為vcf格式
    vcards = ''
    for line in ftext_list[1:]:
        tel_numbers = ''
        name_tel_list = line.strip().split(',')
        if name_tel_list[0]:
            tel_name = name_tel_list[0]  # 姓名
            for tel in name_tel_list[1:]:  # 電話
                tel_numbers += f'TEL;CELL:{tel}\n'
            vcard = f'BEGIN:VCARD\nN:{tel_name}\n{tel_numbers}END:VCARD\n'
            vcards += vcard
    # 3.保存轉(zhuǎn)換后的vcf格式文件
    fname = get_fpath_fname_fextension(csv_filename)
    with open(f'{fname[0]}/{fname[1]}.vcf', "w", encoding='utf-8') as f:
        try:
            f.write(vcards)
        finally:
            f.close()


def vcf22csv(file):
    if not os.path.isfile(file):
        msg.showerror(message="文件不存在!")
    else:
        a = get_fpath_fname_fextension(file)[2]
        if a == ".csv":
            csv2vcf(file)
            msg.showinfo(message="轉(zhuǎn)換成功!此文件為csv文件,已生成vcf文件彤叉。")
        elif a == ".vcf":
            vcf2csv(file)
            msg.showinfo(message="轉(zhuǎn)換成功康栈!此文件為vcf文件,已生成csv文件矢炼。")
        else:
            msg.showwarning(message="請(qǐng)選擇正確的csv文件或者vsf文件.")


if __name__ == "__main__":
    root = tk.Tk().withdraw()  # 創(chuàng)建tk窗口并隱藏
    filename = tk_file.askopenfilename(title='請(qǐng)選擇vcf或csv文件',
                                       filetypes=[("vcf文件", "*.vcf"), ('csv文件', '*.csv')])
    vcf22csv(filename)

效果演示

最后

[1].代碼截止2019-12-02調(diào)試無(wú)誤剩彬。
[2].如需全部代碼及相關(guān)文件唁奢,留言郵箱。
[3].過(guò)程中有任何問(wèn)題柬焕,歡迎交流审残!Q597966823

??讓知識(shí)或技術(shù)實(shí)現(xiàn)其最大的價(jià)值,歡迎收藏自用斑举、轉(zhuǎn)載分享搅轿,轉(zhuǎn)載請(qǐng)注明原文出處,謝謝富玷!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末璧坟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子赎懦,更是在濱河造成了極大的恐慌雀鹃,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件励两,死亡現(xiàn)場(chǎng)離奇詭異黎茎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)当悔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)傅瞻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)踢代,“玉大人,你說(shuō)我怎么就攤上這事嗅骄「炜妫” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵掸读,是天一觀的道長(zhǎng)串远。 經(jīng)常有香客問(wèn)我宏多,道長(zhǎng)儿惫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任伸但,我火速辦了婚禮肾请,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘更胖。我一直安慰自己铛铁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布却妨。 她就那樣靜靜地躺著饵逐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彪标。 梳的紋絲不亂的頭發(fā)上倍权,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音捞烟,去河邊找鬼薄声。 笑死,一個(gè)胖子當(dāng)著我的面吹牛题画,可吹牛的內(nèi)容都是我干的默辨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼苍息,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缩幸!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起竞思,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤表谊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后衙四,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铃肯,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年传蹈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了押逼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片步藕。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挑格,靈堂內(nèi)的尸體忽然破棺而出咙冗,到底是詐尸還是另有隱情,我是刑警寧澤漂彤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布雾消,位于F島的核電站,受9級(jí)特大地震影響挫望,放射性物質(zhì)發(fā)生泄漏立润。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一媳板、第九天 我趴在偏房一處隱蔽的房頂上張望桑腮。 院中可真熱鬧,春花似錦蛉幸、人聲如沸破讨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)提陶。三九已至,卻和暖如春匹层,著一層夾襖步出監(jiān)牢的瞬間隙笆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工又固, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仲器,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓仰冠,卻偏偏與公主長(zhǎng)得像乏冀,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子洋只,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348