Daniel
Daniel

Reputation: 1219

Read Parameters out of icalendar file with JS

I'd like to read several parameters out of an iCalendar file with JavaScript.

The file input looks like:

BEGIN:VEVENT DTSTART:20121127T190000Z DTEND:20121127T210000Z DTSTAMP:20121130T185808Z UID:[email protected] CREATED:20121102T191519Z DESCRIPTION:1. Bundesliga\, 14. Spieltag \n\nhttp://www.fussball-spielplan. info LAST-MODIFIED:20121127T211459Z LOCATION:Commerzbank-Arena\, Frankfurt SEQUENCE:10 STATUS:CONFIRMED SUMMARY:Eintracht Frankfurt - 1. FSV Mainz 05 (1:3) TRANSP:TRANSPARENT END:VEVENT

The parameter tags are:

DTSTART:
DTEND:
DTSTAMP:
UID:
CREATED:
DESCRIPTION:
LAST-MODIFIED:
LOCATION:
STATUS:
SUMMARY:
TRANSP:

I want to read the values behind these parameters. The length of the values are mostly variable.

Using a RegExp is quite hard as I currently don't know what to set as a delimiter. "\n" doesn't work as all text parts are separated by a space. But if I use the space delimiter "\s" it will separate after each word, which is not the wanted result especially for the parameter DESCRIPTION: with a longer text included.

My source code looks currently like this:

file_reader.onload = function (evt) {
document.getElementById("filedrag").textContent = evt.target.result;

Output(
    "<p>File information: <strong>" + file.name +
    "</strong> type: <strong>" + file.type +
    "</strong> size: <strong>" + file.size +
    "</strong> bytes</p>");

var regexp = new RegExp("/DTSTART:(.*?)\s/", "g"); 
var file_content = evt.target.result;
var match, matches = [];

while ((match = regexp.exec(file_content)) != null) {
    matches.push(match.index);
}

alert(matches);
}

Any ideas, how I can achieve my idea?

Upvotes: 0

Views: 159

Answers (2)

MikeM
MikeM

Reputation: 13641

In your code you have

var regexp = new RegExp("/DTSTART:(.*?)\s/", "g"); 

but the regular expression delimiter / is not required when passing a string to the RegExp constructor - it will be interpreted as a character to be matched. Also, as its a string any special RegExp characters need to be double escaped, so \s should be \\s.

Here is one way of getting the values for each specified tag:

var match,
    matches = [],
    tags = 'DTSTART|DTEND|DTSTAMP|UID|CREATED|DESCRIPTION|' +
           'LAST-MODIFIED|LOCATION|STATUS|SUMMARY|TRANSP',
    regexp = new RegExp( '(?:' +  tags + '):([\\s\\S]*?)(?=\\s+(?:' +
                                  tags + '|SEQUENCE|END):)', 'g' );   

while ( match = regexp.exec( file_content ) ) {
    matches.push( match[1] );
}

If you want to retrieve each tag:value pair, change match[1] to match[0].

The above assumes that there is at least one space or newline character before each tag.
It also assumes that a space followed by a tag name followed by a : does not appear in any tag's value.

[\\s\\S] is used instead of . so that newline characters can be included in a tag's value.

The above does not capture the value of the SEQUENCE tag as it was not specified in the list.
If you want to capture it, just add it to tags and remove it from regexp so '|SEQUENCE|END):)' becomes '|END):)'.

Alternatively:

var m,
    params = {},
    rex = /([A-Z-]+):([\s\S]*?)(?=\s+[A-Z-]+:|$)/g;   

while ( m = rex.exec( file_content ) ) {
    params[ m[1] ] = m[2];
}

console.log( params["DTSTART"] );    // 20121127T190000Z

Upvotes: 2

Christophe
Christophe

Reputation: 28154

var params={};
fileContent.replace(/([\w-]+):([^:]+)\s/g,function($0,$1,$2){params[$1]=$2;});

The above regex assumes that:

  • your parameters are single words (no space) followed by a colon ([\w-]+):
  • the values don't contain colons ([^:]+)

If your values (for example the DESCRIPTION text) can contain colons, then you'll need to be more specific about the parameters (cf. @MikeM's answer).

Live demo: http://jsfiddle.net/zhsLJ/

Upvotes: 1

Related Questions