Text::VCardFast(3)
π Text::VCardFast π
okay so bestie, welcome to Text::VCardFast, a Perl extension for very fast parsing of VCards. no cap, it's literally in the name. β¨
πΈ SYNOPSIS πΈ
use Text::VCardFast;
my $hash = Text::VCard::vcard2hash($card, multival => ['adr', 'org', 'n']);
my $card = Text::VCard::hash2vcard($hash, "\r\n");
π¦ DESCRIPTION π¦
Text::VCardFast is designed to parse VCards very quickly compared to pure-perl solutions. it ships with a perl version and an XS version of the same API, reachable as vcard2hash_pp and vcard2hash_c, and the XS one is the preferred one. periodt. π
so like, why would you even care? story time: they were writing the calendaring code for fastmail.fm, and it was taking over 6 seconds to draw / respond to a request for calendar data, and the bulk of that was going to the perl middleware layer β and THAT profiled down to the vcard parser. π the way that a single parser can just eat your whole afternoon.
two of them independently wrote better pure perl implementations, and each one led to about a 5 times speedup. so naturally the thought was: hmm, would XS be much better? here's the benchmark on the v4 example from Wikipedia:
Benchmark: timing 10000 iterations of fastxs, pureperl, vcardasdata...
fastxs: 0 wallclock secs ( 0.16 usr + 0.01 sys = 0.17 CPU) @ 58823.53/s (n=10000)
(warning: too few iterations for a reliable count)
pureperl: 1 wallclock secs ( 1.04 usr + 0.00 sys = 1.04 CPU) @ 9615.38/s (n=10000)
vcardasdata: 8 wallclock secs ( 7.35 usr + 0.00 sys = 7.35 CPU) @ 1360.54/s (n=10000)
(see bench.pl in the source tarball for the code π)
π EXPORT π
vcard2hash
hash2vcard
β API β
Text::VCard::vcard2hash($card, %options);
Options, bestie, listen up:
only_oneβ a flag which, if true, means parsing will stop after extracting a single VCard from the buffer. this is very useful in cases where, for example, a disclaimer has been added after a calendar event in an email. πmultivalβ a list of entry names which will be considered to have multiple values. instead of having a'value'field in the hash, entries with this key will have a'values'field containing an arrayref of values β even if there is only one value. the value is split on semicolon, with escaped semicolons decoded correctly within each item. default is the empty list.multiparamβ as with values,multiparamis a list of entry names which can have multiple values. to see the difference here you must consider something like this:
EMAIL;TYPE="INTERNET,HOME";TYPE=PREF:example@example.com
if 'multiparam' includes 'TYPE' then the result will be: ['INTERNET', 'HOME', 'PREF'], otherwise it will be: ['INTERNET,HOME', 'PREF'].
default is the empty list.
barekeysβ if set, then a bare parameter will be considered to be a parameter name with an undefined value, rather than being a value for the parameter type.
consider:
EMAIL;INTERNET;HOME:example@example.com
barekeys off:
{
name => 'email',
params => { type => ['INTERNET', 'HOME'] },
value => 'example@example.com',
}
barekeys on:
{
name => 'email',
params => { internet => [undef], home => [undef] },
value => 'example@example.com',
}
default is barekeys off.
the input is a scalar containing VFILE text, as per RFC 6350 or the various earlier RFCs it replaces. if the perl unicode flag is set on the scalar, then it will be propagated to the output values. β¨
the output is a hash reference containing a single key 'objects', which is an array of all the cards within the source text.
each object can have the following keys:
typeβ the text afterBEGIN:andEND:of the card (lower cased)propertiesβ a hash from name to array of instances within the card.objectsβ an array of sub cards within the card.
properties are a hash with the following keys:
groupβ optional β if the propery name as'foo.bar', this will befoo.nameβ a copy of the hash key that pointed to this property, so that this hash can be used without keeping the key around tooparamsβ a hash of the parameters on the entry. this is everything from the;to the:valueβ either a scalar (if not a multival field) or an array of values. this is everything after the:
decoding is done where possible, including RFC 6868 handling of ^.
all names, both entry names and parameter names, are lowercased where the RFC says they are not case significant. this means that all hash keys are lowercase within this API, as are card types. π
values, on the other hand, are left in their original case even where the RFC says they are case insignificant β due to the increased complexity of tracking which version what parameters are in effect.
Text::VCard::hash2vcard($hash, $eol)
the inverse operation (as much as possible!) π«Ά
given a hash with an 'objects' key in it, output a scalar string containing the VCARD representation. lines are separated with the $eol string given, or the default "\n". use "\r\n" for files going to caldav/carddav servers.
in the inverse of the above case, where names are case insignificant, they are generated in UPPERCASE in the card, for maximum compatibility with other implementations.
π EXAMPLES π
for more examples see the t/cases directory in the tarball, which contains some sample VCARDs and JSON dumps of the hash representation. π
BEGIN:VCARD
KEY;PKEY=PVALUE:VALUE
KEY2:VALUE2
END:VCARD
{
'objects' => [
{
'type' => 'vcard',
'properties' => {
'key2' => [
{
'value' => 'VALUE2',
'name' => 'key2'
}
],
'key' => [
{
'params' => {
'pkey' => [
'PVALUE'
]
},
'value' => 'VALUE',
'name' => 'key'
}
]
}
}
]
}
BEGIN:VCARD
BEGIN:SUBCARD
KEY:VALUE
END:SUBCARD
END:VCARD
{
'objects' => [
{
'objects' => [
{
'type' => 'subcard',
'properties' => {
'key' => [
{
'value' => 'VALUE',
'name' => 'key'
}
]
}
}
],
'type' => 'vcard',
'properties' => {}
}
]
}
BEGIN:VCARD
GROUP1.KEY:VALUE
GROUP1.KEY2:VALUE2
GROUP2.KEY:VALUE
END:VCARD
{
'objects' => [
{
'type' => 'vcard',
'properties' => {
'key2' => [
{
'group' => 'group1',
'value' => 'VALUE2',
'name' => 'key2'
}
],
'key' => [
{
'group' => 'group1',
'value' => 'VALUE',
'name' => 'key'
},
{
'group' => 'group2',
'value' => 'VALUE',
'name' => 'key'
}
]
}
}
]
}
π SEE ALSO π
there's a similar module Text::VFile::asData on CPAN, but it is much slower and doesn't do as much decoding. π
code is stored on github at
https://github.com/brong/Text-VCardFast/
π AUTHOR π
Bron Gondwana, <brong@fastmail.fm<gt>
π COPYRIGHT AND LICENSE π
Copyright (C) 2014 by Bron Gondwana
this library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.14.2 or, at your option, any later version of Perl 5 you may have available.
and that's the whole page bestie, mwah π no notes.
signing off: this was Text::VCardFast(3) from the perl v5.42.0 manual, dated 2025-07-25 β go parse some cards and slay β¨ππ
π¦ where this page comes from
- fedora 43: perl-Text-VCardFast 0.11-31.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms