2
\$\begingroup\$

I have this regexp working, simple, but I feel like it may not be the best way to code it. Basically, I have a playlist separated by line breaks returned as tcp data like so:

file: http://192.168.100.214/Music/justchill.mp3
Artist: Brian G
Title: Just Chill
Track: 1
Date: 2014
Genre: Instrumental
Pos: 0
Id: 0
file: http://192.168.100.214/Music/justchill.mp3
Pos: 1
Id: 1
file: http://streaming.radionomy.com/ABC-Lounge
Pos: 2
Id: 2
OK

Now you can see the fields aren't always the same, but they always start with file and have the pos and id, always ending with id. I'm, parsing this data by line break to create an object, and then slicing it out of the string. Then I run the regexp on the new string, repeat while checking for Id: If it finds Id, I create a new object and start the whole process over.

It works fine, but I don't know, just feels like there may be a more efficient way to do it.

var parseplaylist = function(data)
{
 var pattern = /(.+): (.+)\n/;
 var result = pattern.exec(data);
 var playlistarray = [];
 if (result !== null)
 {
 var playlistobject = {};
 while (result !== null)
 {
 playlistobject[result[1]] = result[2];
 if (result[1] == "Id")
 {
 playlistarray[playlistobject.Pos] = playlistobject;
 playlistobject = {};
 }
 data = data.substr(result[0].length);
 result = pattern.exec(data);
 }
 }
 return playlistarray;
};
asked Apr 18, 2014 at 20:38
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

You can use the String.prototype.replace function to "loop" through all the relevant lines of the data. It accepts a regex pattern, and a function to handle the the matched text and return the replacement text. Here, however, we don't care about actually replacing anything; we just use it to find each key/value pair

function parsePlaylist(data) {
 var tracks = [], currentTrack;
 // do a multi-line replace-all for "(key): (value)", but don't
 // bother actually replacing anything, or storing the resulting
 // string. We're just using it to walk through the data
 data.replace(/^([^:]+):\s*(.+)$/gmi, function (match, key, value) {
 // if this is the start of a new track (indicated
 // by a "file" field), or the start of the loop,
 // create a new object to hold the data
 if( !currentTrack || key === "file" ) {
 currentTrack = {};
 tracks.push(currentTrack);
 }
 // add the key/value pair
 currentTrack[key] = value;
 });
 return tracks;
}

That'll give you this:

[ { file: 'http://192.168.100.214/Music/justchill.mp3',
 Artist: 'Brian G',
 Title: 'Just Chill',
 Track: '1',
 Date: '2014',
 Genre: 'Instrumental',
 Pos: '0',
 Id: '0' },
 { file: 'http://192.168.100.214/Music/justchill.mp3',
 Pos: '1',
 Id: '1' },
 { file: 'http://streaming.radionomy.com/ABC-Lounge',
 Pos: '2',
 Id: '2' } ]
answered Apr 18, 2014 at 21:01
\$\endgroup\$
2
  • \$\begingroup\$ Whoa! Awesome man thank you so much, that's much more efficient. \$\endgroup\$ Commented Apr 18, 2014 at 21:49
  • \$\begingroup\$ @BrianGe No problem. Glad it's useful. \$\endgroup\$ Commented Apr 18, 2014 at 21:57

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.