Reputation: 1219
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
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
Reputation: 28154
var params={};
fileContent.replace(/([\w-]+):([^:]+)\s/g,function($0,$1,$2){params[$1]=$2;});
The above regex assumes that:
([\w-]+):
([^:]+)
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