0

I'm trying to see if there's something that exists to do the following. I'd hate to reinvent the wheel.

I have a string like this. It's a file name.

2014-12-22-thomas-javascript.md

I want to be able to provide a format for this schema.

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

And I'd like an object in return.

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

This way of providing a string and a format is very reticent of these two functions from node core util, moment parse, and jekyll post names.

ThomasReggi
  • 55,053
  • 85
  • 237
  • 424
  • This is an obvious use of regular expression. – Barmar Dec 22 '14 at 22:30
  • @Barmar I guess I was looking for more of a library that could plug in and be used with any string / format, not just writing a regular expression every time I'd like to parse a string. – ThomasReggi Dec 22 '14 at 22:31
  • What do you think the input to the library will be? It's not like your string is a well-known format that someone would have written a library for. – Barmar Dec 22 '14 at 22:32
  • And requests for software recommendations are off-topic here. – Barmar Dec 22 '14 at 22:33
  • @Barmar a library as I'm explaining that can handle any use case for a string isn't that farfetched. – ThomasReggi Dec 22 '14 at 22:34
  • My point is that a general-purpose library will require you to provide it with a pattern. What do you think a regular expression is? – Barmar Dec 22 '14 at 22:35
  • @Barmar I'm talking a library that would abstract the pattern from `{year}-{month}-{day}-{name}-{topic}.{extension}`. – ThomasReggi Dec 22 '14 at 22:35
  • OK, that's a reasonable desire. But from http://stackoverflow.com/help/on-topic: _Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam._ – Barmar Dec 22 '14 at 22:38
  • @Barmar but when I do it here it's ok? http://stackoverflow.com/questions/27245652/create-a-simpler-way-of-nesting-functions – ThomasReggi Dec 22 '14 at 22:40
  • If you're using a library such as underscore or jQuery, and have a question about how to use it correctly, that's on-topic. But it's not appropriate to use us as a google search service. – Barmar Dec 22 '14 at 22:41
  • @Barmar Thank you for your time. Sorry for the post. – ThomasReggi Dec 22 '14 at 22:44
  • 1
    Isn't this a simple string manipulation task? No need for a library, just create a function to do what you need. Create an object, split the string with `-` and iterate the resulted array and add some properties to the object, return the newly-created object. 15 lines max... – Teemu Dec 22 '14 at 23:14
  • @Teemu I currently have three use cases for this and I'd like one interface / function for processing them all. – ThomasReggi Dec 22 '14 at 23:16
  • How about to show the two more cases? – Teemu Dec 22 '14 at 23:17
  • @Teemu the cases consist of any imaginable file name and schema. – ThomasReggi Dec 22 '14 at 23:18

2 Answers2

3

At the risk of reinventing a wheel;

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;
    }
}

No doubt there are a bunch of ways this will break but works with your example;

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

EDIT

And for performing the reverse;

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;
    }
}

Which can accept named object members or positional for non-objects.

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

20-xyzabc-2014-StackOverflow

Dave Anderson
  • 11,836
  • 3
  • 58
  • 79
  • Thank you so much! I really hope you didn't write this just for this. I really wasn't looking for someone to do it for me! – ThomasReggi Dec 23 '14 at 03:34
  • @ThomasReggi no problem, I've edited the post with my format function as well which can help go the other way. – Dave Anderson Dec 23 '14 at 04:54
0

I found the code in Hexo, it's like jekyll but built with node.

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, ...}
ThomasReggi
  • 55,053
  • 85
  • 237
  • 424