Example unfolded:
with open(vcf_file_path, 'r', encoding='utf-8') as f: for line in f: line = line.strip() if not line: continue if line == "BEGIN:VCARD": current_contact = {} elif line == "END:VCARD": if current_contact: contacts.append(current_contact) current_contact = None else: prop, value, params = parse_vcf_line(line) if prop == "VERSION": current_contact['version'] = value elif prop == "FN": current_contact['fullName'] = value elif prop == "N": # N:last;first;middle;prefix;suffix parts = value.split(';') current_contact['lastName'] = parts[0] current_contact['firstName'] = parts[1] if len(parts) > 1 else '' current_contact['middleName'] = parts[2] if len(parts) > 2 else '' current_contact['prefix'] = parts[3] if len(parts) > 3 else '' current_contact['suffix'] = parts[4] if len(parts) > 4 else '' elif prop == "EMAIL": if 'email' not in current_contact: current_contact['email'] = [] current_contact['email'].append(value) elif prop == "TEL": if 'phone' not in current_contact: current_contact['phone'] = [] phone_entry = 'number': value if 'type' in params: phone_entry['type'] = params['type'] current_contact['phone'].append(phone_entry) elif prop == "ADR": # ADR: ;street;city;region;code;country parts = value.split(';') # Typically parts[0] = PO box, parts[1] = extended, parts[2] = street, etc. if len(parts) >= 6: current_contact['address'] = 'street': parts[2], 'city': parts[3], 'region': parts[4], 'code': parts[5], 'country': parts[6] if len(parts) > 6 else '' elif prop == "ORG": current_contact['organization'] = value return contacts contacts_json = vcf_to_json('input.vcf') with open('output.json', 'w') as f: json.dump(contacts_json, f, indent=2) 5. Handling Complex vCard Features 5.1 Groups and Multiple Entries vCard supports grouping (e.g., item1.EMAIL;TYPE=work ). A robust converter must parse the group prefix and reconstruct it in JSON, usually as nested objects. 5.2 Binary Data (Photos/Logos) vCard can embed base64-encoded images ( PHOTO;ENCODING=b;TYPE=JPEG:... ). Convert to JSON as a base64 string and optionally decode to a URL or file reference. 5.3 Custom Properties (X- extensions) Properties like X-ABUID (Apple Address Book UID) should be preserved in JSON under a custom or x-properties object. 5.4 Multi-line Values (Folded Lines) vCard 3.0 uses folding: a line starting with a space or tab continues the previous property. A parser must unfold these before processing. json vcf 変換
Converting between JSON and VCF is a common task when migrating contact data between web applications (which often use JSON) and legacy or mobile systems (which rely on VCF). This guide covers both directions of conversion, including specifications, code examples, edge cases, and tooling. 2.1 The VCF (vCard) Format A simple vCard 4.0 example: A robust converter must parse the group prefix
# Full name lines.append(f"FN:contact.get('fullName', '')") Convert to JSON as a base64 string and