2014-12-22 7 views
0

Я пытаюсь выяснить, существует ли что-то, что существует, чтобы сделать следующее. Мне не хотелось бы изобретать велосипед.Извлечь переменные из форматированной строки

У меня есть такая строка. Это имя файла.

2014-12-22-thomas-javascript.md 

Я хочу, чтобы обеспечить формат для этой схемы.

{year}-{month}-{day}-{name}-{topic}.{extension} 

И я хотел бы получить объект в обмен.

{ 
    "year": "2014", 
    "month": "12", 
    "day": "22", 
    "name": "thomas", 
    "topic": "javascript", 
    "extension": "md" 
} 

Этот способ обеспечить строку и формат очень сдержан из этих двух функций из основного узла Util, момент разбора, и Джекил почтовых имен.

+0

Это очевидное использование регулярного выражения. – Barmar

+0

@Barmar Я думаю, я искал больше библиотеки, которая могла бы подключаться и использоваться с любой строкой/форматом, а не просто писать регулярное выражение каждый раз, когда я хотел бы разбирать строку. – ThomasReggi

+0

Как вы думаете, каким будет вход в библиотеку? Это не похоже на то, что ваша строка - это хорошо известный формат, для которого кто-то написал бы библиотеку. – Barmar

ответ

3

На риск изобретать колесо;

String.parse = function parse() { 
    if(typeof arguments[0] === 'string' && typeof arguments[1] === 'string') { 
     var str = arguments[0]; 
     var val = arguments[1]; 
     var array = [], obj = {}; 

     var re = /(?:{)([a-z]*)(?:})/gi; 
     var match, sre = str; 
     while(match = re.exec(str)) { 
      array.push(match[1]); 
      sre = sre.replace(match[0], '(\\w*)');   
     } 

     re = new RegExp(sre); 
     var matches = val.match(re); 
     if(matches) { 
      for(var i = 1; i < matches.length; i++) { 
       obj[array[i-1]] = matches[i];  
      } 
     } 
     return obj; 
    } 
} 

Несомненно, существует множество способов, которыми это может сломаться, но работает с вашим примером;

String.parse("{year}-{month}-{day}-{name}-{topic}.{extension}", "2014-12-22-thomas-javascript.md");

РЕДАКТИРОВАТЬ

И для выполнения обратного;

String.format = function format() { 
    if (typeof arguments[0] === 'string') { 
     var s = arguments[0]; 

     var re = /(?:{)(\d*)(?:})/gi; 
     var a, i, match, search = s; 
     while (match = re.exec(search)) { 
      for (i = 1; i < arguments.length; i++) { 
       a = parseInt(match[1]) + 1; 
       s = s.replace(match[0], typeof arguments[a] !== 'object' ? arguments[a] || '' : ''); 
      } 
     } 

     re = /(?:{)([a-z]*)(?:})/gi; 
     match, search = s; 
     while (match = re.exec(search)) { 
      for (i = 1; i < arguments.length; i++) { 
       if (arguments[i].hasOwnProperty(match[1])) { 
        s = s.replace(match[0], arguments[i][match[1]]); 
       } 
      } 
     } 
     return s; 
    } 
} 

который может принимать именованные элементы объекта или позиционные для объектов, не являющихся объектами.

String.format("{0}-{name}{1}-{year}-{src}", 20, "abc", { name: "xyz", year: 2014 }, { src: 'StackOverflow' });

20-xyzabc-2014-StackOverflow

+0

Большое вам спасибо! Надеюсь, ты не написал это только для этого. Я действительно не искал, чтобы кто-то сделал это для меня! – ThomasReggi

+0

@ThomasReggi не проблема, я тоже редактировал сообщение с моей функцией формата, которая может помочь пойти другим путем. –

0

Я нашел код Hexo, это как Джекил, но построенный с узлом.

var Permalink = require('hexo-util').Permalink; 
var permalink = new Permalink(':year-:month-:day-:name-:topic.:extension 
', { 
    segments: { 
     year: /(\d{4})/, 
     month: /(\d{2})/, 
     day: /(\d{2})/ 
    } 
}); 

permalink.parse('2014-12-22-thomas-javascript.md'); 
// {year: 2014, month: 12, day: 22, ...} 
Смежные вопросы