Skip to content

Instantly share code, notes, and snippets.

@andyg2
Last active October 28, 2023 00:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andyg2/3cf2f6e76da36171ae265f0805e08bc8 to your computer and use it in GitHub Desktop.
Save andyg2/3cf2f6e76da36171ae265f0805e08bc8 to your computer and use it in GitHub Desktop.
A regulalr expression based JavaScript VCARD parser into a JSON
{
"adr": [
{
"meta": {
"TYPE": "INTL",
"TYPE1": "PARCEL",
"TYPE2": "WORK"
},
"value": [
"",
"",
"UltraMobile Street",
"Planet Earth",
"Milky Way",
"2134",
""
]
},
{
"meta": {
"TYPE": "DOM",
"TYPE1": "PARCEL",
"TYPE2": "HOME"
},
"value": [
"",
"",
"Enabled Avenue",
"Planet Erath",
"Milky Way",
"1234",
""
]
}
],
"email": [
{
"meta": {
"TYPE": "home"
},
"value": [
"home@domain.com"
]
},
{
"meta": {
"TYPE": "office"
},
"value": [
"office@domain.com"
]
},
{
"meta": {
"TYPE": "personal"
},
"value": [
"personal@domain.com"
]
}
],
"org": "Enabled",
"tel": [
{
"meta": {
"TYPE": "mobile"
},
"value": [
"+1 234 567 890"
]
},
{
"meta": {
"TYPE": "office"
},
"value": [
"+1 234 567 890"
]
},
{
"meta": {
"TYPE": "personal"
},
"value": [
"+1 234 567 890"
]
}
],
"title": "Photographer",
"url": [
{
"meta": {
"TYPE": "WORK"
},
"value": [
"www.domain.com"
]
},
{
"meta": {
"TYPE": "facebook"
},
"value": [
"www.facebook.com"
]
},
{
"meta": {
"TYPE": "twitter"
},
"value": [
"www.twitter.com"
]
},
{
"meta": {
"TYPE": "google plus"
},
"value": [
"www.googleplus.com"
]
}
]
}
<pre>BEGIN:VCARD
N:Black;Karla;;Mrs;
ADR;INTL;PARCEL;WORK:;;UltraMobile Street;Planet Earth;Milky Way;2134;
ADR;DOM;PARCEL;HOME:;;Enabled Avenue;Planet Erath;Milky Way;1234;
EMAIL;home:home@domain.com
EMAIL;office:office@domain.com
EMAIL;personal:personal@domain.com
ORG:Enabled
TEL;mobile:+1 234 567 890
TEL;office:+1 234 567 890
TEL;personal:+1 234 567 890
TITLE:Photographer
URL;WORK:www.domain.com
URL;facebook:www.facebook.com
URL;twitter:www.twitter.com
URL;google plus:www.googleplus.com
END:VCARD
</pre>
function parse(input) {
var Re1 = /^(version|fn|title|org):(.+)$/i;
var Re2 = /^([^:;]+);([^:]+):(.+)$/;
var ReKey = /item\d{1,2}\./;
var fields = {};
input.split(/\r\n|\r|\n/).forEach(function (line) {
var results, key;
if (Re1.test(line)) {
results = line.match(Re1);
key = results[1].toLowerCase();
fields[key] = results[2];
} else if (Re2.test(line)) {
results = line.match(Re2);
key = results[1].replace(ReKey, '').toLowerCase();
var meta = {};
results[2].split(';')
.map(function (p, i) {
var match = p.match(/([a-z]+)=(.*)/i);
if (match) {
return [match[1], match[2]];
} else {
return ["TYPE" + (i === 0 ? "" : i), p];
}
})
.forEach(function (p) {
meta[p[0]] = p[1];
});
if (!fields[key]) fields[key] = [];
fields[key].push({
meta: meta,
value: results[3].split(';')
})
}
});
return fields;
};
var $ = function(selector) {
return document.querySelector(selector);
};
$('pre').innerHTML = JSON.stringify(
parse(document.body.innerText), 0, 2
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment