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;
};
\$\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' } ]
\$\endgroup\$
2
  • \$\begingroup\$ Whoa! Awesome man thank you so much, that's much more efficient. \$\endgroup\$
    – Brian Ge
    Commented Apr 18, 2014 at 21:49
  • \$\begingroup\$ @BrianGe No problem. Glad it's useful. \$\endgroup\$
    – Flambino
    Commented Apr 18, 2014 at 21:57

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.