Преобразовать строку с разделителями в массив объектов в Javascript - PullRequest
0 голосов
/ 17 марта 2020

CLI сервера мультимедиа Logitech возвращает список медиаплееров в сети в виде строки. После того, как я удалил несколько начальных параметров, у меня осталось следующее:

playerindex:0 playerid:00:04:20:17:df:db
uuid:e03808651b33791ebd7654ecb558a659 ip:192.168.2.213:20806
name:Living Room Duet seq_no:0 model:receiver modelname:Squeezebox
Receiver power:1 isplaying:1 displaytype:none isplayer:1 canpoweroff:1
connected:1 firmware:77 playerindex:1 playerid:00:04:20:17:1c:ea
uuid:6366878c87380f33779c3832be86b4eb ip:192.168.2.214:19359
name:Bedroom seq_no:0 model:receiver modelname:Squeezebox Receiver
power:1 isplaying:0 displaytype:none isplayer:1 canpoweroff:1
connected:1 firmware:77 playerindex:2 playerid:00:04:20:1e:d3:59
uuid:1c8b751b20f7e4c6977e98de03060a53 ip:192.168.2.215:23163
name:Living Room seq_no:0 model:boom modelname:Squeezebox Boom power:1
isplaying:0 displaytype:graphic-160x32 isplayer:1 canpoweroff:1
connected:1 firmware:57

ПРИМЕЧАНИЕ: выше вставлено с символами новой строки, НЕ в исходной строке, для простоты чтения ( и был также отредактирован другим пользователем, чтобы сделать его более читабельным). В строке НЕТ символов новой строки.

Как видите, строка разделена пробелами, однако вы можете заметить, что в именах игроков есть пробел. Поэтому я не могу просто использовать newArray = array.split(" "), а затем l oop через x параметров для построения массива объектов, что является моей целью, потому что эти пробелы отбрасывают кусочную длину массива.

Вторая проблема, которую я могу заметить, состоит в том, что IP-адрес и адреса MA C содержат двоеточия, что вызывает дополнительную проблему.

Как этого добиться?

Ответы [ 3 ]

1 голос
/ 17 марта 2020

Это можно сделать вручную, потому что свойства не имеют случайной позиции, поэтому мы можем разделить каждое известное свойство.

var str = '...your string here...';

// Remove new line and split `playerindex`
var split = str.split("\n").join(' ').split('playerindex:');
var take = ['playerindex', 'playerid', 'uuid', 'ip', 'name', 'seq_no', 'model', 'modelname', 'power', 'isplaying', 'displaytype', 'isplayer', 'canpoweroff', 'connected', 'firmware'];

// Remove empty string
split.shift();

var collection = [];
for(var i=0; i<split.length; i++){

  // Prepare the object and current string to be parsed
  var currentData = {};
  var currentStr = split[i];

  // Split each known property
  for(var j=1; j<take.length; j++){
    currentStr = currentStr.split(' '+take[j]+':', 2);

    // Does the property not exist?
    if(currentStr.length === 1){
      currentStr = currentStr[0];
      continue;
    }

    // The first index is value from the previous property
    currentData[take[j-1]] = currentStr[0];

    // The last index still need to be parsed
    currentStr = currentStr[1];
  }

  // Put the last string as the last property value
  currentData[take[j-1]] = currentStr.trim();

  // Finished, let's push to the collection
  collection.push(currentData);
}

console.log(collection);
0 голосов
/ 17 марта 2020

Вы можете использовать регулярные выражения для нескольких совпадений |, чтобы извлечь данные в формате:

const re = /(playerindex):(\d+)|(playerid):(([0-9a-f]{2}:?){6})|(uuid):([0-9a-f]{32})|(ip):(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)|(\sname):((\w+)\s)+|(seq_no):(\d+)|(model):(\w+)|(modelname):((\w+)\s)+|(power):(\d+)|(isplaying):(\d)|(displaytype):([a-z\-0-9]+)|(isplayer):(\d)|(canpoweroff):(\d)|(connected):(\d)|(firmware):(\d+)/gi;

const formatted = `playerindex:0 playerid:00:04:20:17:df:db uuid:e03808651b33791ebd7654ecb558a659 ip:192.168.2.213:20806
name:Living Room Duet seq_no:0 model:receiver modelname:Squeezebox
Receiver power:1 isplaying:1 displaytype:none isplayer:1 canpoweroff:1
connected:1 firmware:77 playerindex:1 playerid:00:04:20:17:1c:ea
uuid:6366878c87380f33779c3832be86b4eb ip:192.168.2.214:19359
name:Bedroom seq_no:0 model:receiver modelname:Squeezebox Receiver
power:1 isplaying:0 displaytype:none isplayer:1 canpoweroff:1
connected:1 firmware:77 playerindex:2 playerid:00:04:20:1e:d3:59
uuid:1c8b751b20f7e4c6977e98de03060a53 ip:192.168.2.215:23163
name:Living Room seq_no:0 model:boom modelname:Squeezebox Boom power:1
isplaying:0 displaytype:graphic-160x32 isplayer:1 canpoweroff:1
connected:1 firmware:57`.replace("\n", ' ');

const group = formatted.match(re).reduce((acc, cur, arr) => {
  let [, name, value] = cur.match(/(\w+):(.*)/);
  name = name.trim();

  let entry;

  if (name === 'playerindex') {
    entry = {}
    acc.push(entry);
  } else {
    entry = acc[acc.length - 1];
  }

  entry[name] = value.trim();

  return acc;
}, []);


document.getElementById('out').textContent = JSON.stringify(group, null, 2);
<pre id="out"><pre>
0 голосов
/ 17 марта 2020

Если я правильно понял ваш вопрос, то, что, безусловно, работает в приведенном вами примере, это поставить \n вместо последнего пробела перед последовательностью непробельных символов \S сразу после на :; и затем разделение строки на каждый \n

Например:

var str = "playerindex:0 playe... and the rest of the string...";
var arrayOfSplits = str.replace(/(\s)(\S*\:)/g,"\n$2").split("\n");

Потенциальная проблема, с которой я сталкиваюсь, заключается в том, что предполагается, что не будет никаких \n в строке. Конечно, это можно решить с помощью другого символа / шаблона, который, как известно, не появляется в строке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...