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