2016-03-06 2 views
2

Мне нужно преобразовать это ...JS: Преобразование текста в объекте массив

# 4.0.0 - 2016-01-01 
- some text without category 

# 3.12.0 - 2016-02-01 
- Category: some text 

# 3.11.4 - 2016-03-01 
- Category: some multiple text 
- Something: some text 
- Anything: more text 

... в (объекте) массив. Я не знаю, как сохранить все элементы, связанные с его версией.

Результат должен быть выглядеть следующим образом (например, для последнего блока)

[ 
    { 
     major: 3, 
     minor: 11, 
     patch = 4, 
     date = '2016-03-01', 
     entries = [ 
      { category: 'Category', 'some multiple text' }, 
      { category: 'Something', 'some text' }, 
      { category: 'Anything', 'more text' } 
     ] 
    } 
] 

Как вы можете видеть в первом блоке, в entries поле category является необязательным.

Это, как я пытаюсь сделать это:

var lines = text.split('\n'); 
for(var i = 0;i < lines.length;i++){ 
    var meta = lines[i].split(' '); 
    var version = meta[1].split('.'); 
    result['major'] = version[0]; 
    result['minor'] = version[1]; 
    result['patch'] = version[2]; 
    result['date'] = meta[3] 
} 

Но это работает только для первой строки каждого блока.

+0

ли это быть в 'JavaScript'? Другие двигатели (например, 'PCRE' на PHP) обеспечивают лучшую функциональность, например' \ G'. – Jan

+0

Да, это должен быть JS. – user3142695

ответ

2

Это предложение разделить строку на куски и протестировать чушек для # или -. Эти строки оцениваются и добавляются к результату.

var text = '# 4.0.0 - 2016-01-01\n- some text without category\n- Just a text: with double point\n\n# 3.12.0 - 2016-02-01\n- Category: some text\n\n# 3.11.4 - 2016-03-01\n- Category: some multiple text\n- Something: some text\n- Anything: more text', 
 
    result = function (text) { 
 
     var array = text.split('\n'), 
 
      o, r = []; 
 
     array.forEach(function (a) { 
 
      var p, v; 
 
      if (a[0] === '#') { 
 
       o = {}; 
 
       p = a.match(/^# ((.*) -)?(.*)$/); 
 
       v = p[2].split('.'); 
 
       o.major = v[0]; 
 
       o.minor = v[1]; 
 
       o.patch = v[2]; 
 
       o.date = p[3]; 
 
       r.push(o); 
 
      } 
 
      if (a[0] === '-') { 
 
       if (!o.entries) { 
 
        o.entries = []; 
 
       } 
 
       p = a.match(/^- ((\w*):)?(.*)$/); 
 
       o.entries.push({ category: p[2], value: p[3] }); 
 
      } 
 
     }); 
 
     return r; 
 
    }(text); 
 

 
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

+0

Только одно: категория должна быть только извлечена, если это одно слово. Пример: 'Category: Some Text' даст мне поле категории. Но «Только текст: с двойной точкой» не дает мне поле категории, а только поле значения. – user3142695

+0

@ user3142695, см. Edit, с отредактированным регулярным выражением: '/^- ((\ w *):)? (. *) $ /' Для поиска только слова. –

1

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

var text = `# 4.0.0 - 2016-01-01 
- some text without category 

# 3.12.0 - 2016-02-01 
- Category: some text 

# 3.11.4 - 2016-03-01 
- Category: some multiple text 
- Something: some text 
- Anything: more text`; 

var lines = text.split('\n'); 
var all = []; 
for(var i = 0;i < lines.length;i++){ 
    var firstChar = lines[i].substr(0, 1); 
    if (firstChar === '#'){ 
    all.push(extractVersionInfo(lines[i])); 
    } 
    else if (firstChar === "-"){ 
    all[all.length-1].entries.push(extractNote(lines[i])); 
    } 
} 
console.log(all); 

function extractNote(text){ 
    var withoutDash = text.substr(2); 
    if (withoutDash.indexOf(":") !== -1){ 
    var parts = withoutDash.split(":"); 
    return {category: parts[0], 
     value: parts[1] 
     }; 
    } 
    else { 
    return {value: withoutDash}; 
    } 
} 

function extractVersionInfo(text){ 
    var pattern = /# ([0-9]+)\.([0-9]+)\.([0-9]+) - ([0-9]{4}-[0-9]{2}-[0-9]{2})/; 
    var match = text.match(pattern); 
    result = {}; 
    result.major = match[1]; 
    result.minor = match[2]; 
    result.patch = match[3]; 
    result.date = match[4]; 
    result.entries = []; 
    return result; 
} 

Выходные:

[ { major: '4', 
    minor: '0', 
    patch: '0', 
    date: '2016-01-01', 
    entries: [ { value: 'some text without category' } ] }, 
    { major: '3', 
    minor: '12', 
    patch: '0', 
    date: '2016-02-01', 
    entries: [ { category: 'Category', value: ' some text' } ] }, 
    { major: '3', 
    minor: '11', 
    patch: '4', 
    date: '2016-03-01', 
    entries: 
    [ { category: 'Category', value: ' some multiple text' }, 
     { category: 'Something', value: ' some text' }, 
     { category: 'Anything', value: ' more text' } ] } ] 
Смежные вопросы