lib/base/string.js
function format(str, obj) {

    if (obj instanceof Array) {
        var i = 0, len = obj.length;
        //find the matches
        return str.replace(FORMAT_REGEX, function (m, format, type) {
            var replacer, ret;
            if (i < len) {
                replacer = obj[i++];
            } else {
                //we are out of things to replace with so
                //just return the match?
                return m;
            }
            if (m === "%s" || m === "%d" || m === "%D") {
                //fast path!
                ret = replacer + "";
            } else if (m === "%Z") {
                ret = replacer.toUTCString();
            } else if (m === "%j") {
                try {
                    ret = JSON.stringify(replacer);
                } catch (e) {
                    throw new Error("comb.string.format : Unable to parse json from ", replacer);
                }
            } else {
                format = format.replace(/^\[|\]$/g, "");
                switch (type) {
                case "s":
                    ret = formatString(replacer, format);
                    break;
                case "d":
                    ret = formatNumber(replacer, format);
                    break;
                case "j":
                    ret = formatObject(replacer, format);
                    break;
                case "D":
                    ret = getDate().date.format(replacer, format);
                    break;
                case "Z":
                    ret = getDate().date.format(replacer, format, true);
                    break;
                }
            }
            return ret;
        });
    } else if (isHash(obj)) {
        return str.replace(INTERP_REGEX, function (m, format, value) {
            value = obj[value];
            if (!misc.isUndefined(value)) {
                if (format) {
                    if (comb.isString(value)) {
                        return formatString(value, format);
                    } else if (typeof value === "number") {
                        return formatNumber(value, format);
                    } else if (getDate().isDate(value)) {
                        return getDate().date.format(value, format);
                    } else if (typeof value === "object") {
                        return formatObject(value, format);
                    }
                } else {
                    return "" + value;
                }
            }
            return m;
        });
    } else {
        var args = pSlice.call(arguments).slice(1);
        return format(str, args);
    }
}
function format(str, obj) {

    if (obj instanceof Array) {
        var i = 0, len = obj.length;
        //find the matches
        return str.replace(FORMAT_REGEX, function (m, format, type) {
            var replacer, ret;
            if (i < len) {
                replacer = obj[i++];
            } else {
                //we are out of things to replace with so
                //just return the match?
                return m;
            }
            if (m === "%s" || m === "%d" || m === "%D") {
                //fast path!
                ret = replacer + "";
            } else if (m === "%Z") {
                ret = replacer.toUTCString();
            } else if (m === "%j") {
                try {
                    ret = JSON.stringify(replacer);
                } catch (e) {
                    throw new Error("comb.string.format : Unable to parse json from ", replacer);
                }
            } else {
                format = format.replace(/^\[|\]$/g, "");
                switch (type) {
                case "s":
                    ret = formatString(replacer, format);
                    break;
                case "d":
                    ret = formatNumber(replacer, format);
                    break;
                case "j":
                    ret = formatObject(replacer, format);
                    break;
                case "D":
                    ret = getDate().date.format(replacer, format);
                    break;
                case "Z":
                    ret = getDate().date.format(replacer, format, true);
                    break;
                }
            }
            return ret;
        });
    } else if (isHash(obj)) {
        return str.replace(INTERP_REGEX, function (m, format, value) {
            value = obj[value];
            if (!misc.isUndefined(value)) {
                if (format) {
                    if (comb.isString(value)) {
                        return formatString(value, format);
                    } else if (typeof value === "number") {
                        return formatNumber(value, format);
                    } else if (getDate().isDate(value)) {
                        return getDate().date.format(value, format);
                    } else if (typeof value === "object") {
                        return formatObject(value, format);
                    }
                } else {
                    return "" + value;
                }
            }
            return m;
        });
    } else {
        var args = pSlice.call(arguments).slice(1);
        return format(str, args);
    }
}
function format ( str , obj ) { if ( obj instanceof Array ) { var i = 0 , len = obj . length ; //find the matches return str . replace ( FORMAT_REGEX , function ( m , format , type ) { var replacer , ret ; if ( i < len ) { replacer = obj [ i ++ ] ; } else { //we are out of things to replace with so //just return the match? return m ; } if ( m === "%s" || m === "%d" || m === "%D" ) { //fast path! ret = replacer + "" ; } else if ( m === "%Z" ) { ret = replacer . toUTCString ( ) ; } else if ( m === "%j" ) { try { ret = JSON . stringify ( replacer ) ; } catch ( e ) { throw new Error ( "comb.string.format : Unable to parse json from " , replacer ) ; } } else { format = format . replace ( / ^\[|\]$ / g , "" ) ; switch ( type ) { case "s" : ret = formatString ( replacer , format ) ; break ; case "d" : ret = formatNumber ( replacer , format ) ; break ; case "j" : ret = formatObject ( replacer , format ) ; break ; case "D" : ret = getDate ( ) . date . format ( replacer , format ) ; break ; case "Z" : ret = getDate ( ) . date . format ( replacer , format , true ) ; break ; } } return ret ; } ) ; } else if ( isHash ( obj ) ) { return str . replace ( INTERP_REGEX , function ( m , format , value ) { value = obj [ value ] ; if ( ! misc . isUndefined ( value ) ) { if ( format ) { if ( comb . isString ( value ) ) { return formatString ( value , format ) ; } else if ( typeof value === "number" ) { return formatNumber ( value , format ) ; } else if ( getDate ( ) . isDate ( value ) ) { return getDate ( ) . date . format ( value , format ) ; } else if ( typeof value === "object" ) { return formatObject ( value , format ) ; } } else { return "" + value ; } } return m ; } ) ; } else { var args = pSlice . call ( arguments ) . slice ( 1 ) ; return format ( str , args ) ; } }
Formats a string with the specified format

Format `String`s

```
comb.string.format("%s", "Hello"); // "Hello"
comb.string.format("%10s", "Hello"); // "     Hello"
comb.string.format("%-10s", "Hello"); // ""Hello     ""
comb.string.format('%.10s', "Hello"); //".....Hello"
comb.string.format('%-!10s', "Hello"); //"Hello!!!!!"
comb.string.format("%-.10s%s!", "Hello", "World"); //"Hello.....World!"
```

Formatting Numbers

```
comb.string.format('%d', 10); //"10"

//setting precision
comb.string.format('%.2d', 10); //"10.00"

//specifying width
comb.string.format('%5d', 10); //"   10"

//Signed
comb.string.format('%+d', 10);  //"+10"
comb.string.format('%+d', -10); //"-10"

comb.string.format('% d', 10);  //" 10"
comb.string.format('% d', -10); //"-10"

//width
comb.string.format('%5d', 10); //"   10"

//width and precision
comb.string.format('%6.2d', 10); //" 10.00"

//signed, width and precision
comb.string.format('%+ 7.2d', 10);  //" +10.00"
comb.string.format('%+ 7.2d', -10); //" -10.00"
comb.string.format('%+07.2d', 10);  //"+010.00"
comb.string.format('%+07.2d', -10); //"-010.00"
comb.string.format('%  7.2d', 10);  //"  10.00"
comb.string.format('%  7.2d', -10); //" -10.00"
comb.string.format('% 7.2d', 10);   //"  10.00"
comb.string.format('% 7.2d', -10);  //" -10.00"

//use a 0 as padding
comb.string.format('%010d', 10); //"0000000010"

//use an ! as padding
comb.string.format('%!10d', 10); //"!!!!!!!!10"

//left justify signed ! as padding and a width of 10
comb.string.format('%-+!10d', 10); //"+10!!!!!!!"

```

Formatting dates

```
comb.string.format("%[h:mm a]D", new Date(2014, 05, 04, 7,6,1)); // 7:06 AM - local -
comb.string.format("%[h:mm a]Z", new Date(2014, 05, 04, 7,6,1)); //12:06 PM - UTC
comb.string.format("%[yyyy-MM-dd]D", new Date(2014, 05, 04, 7,6,1)); // 2014-06-04 - local
comb.string.format("%[yyyy-MM-dd]Z", new Date(2014, 05, 04, 7,6,1)); // 2014-06-04 - UTC
```

Formatting Objects

```
//When using object formats they must be in an array otherwise
//format will try to interpolate the properties into the string.
comb.string.format("%j", [{a : "b"}]) // '{"a":"b"}'

//Specifying spacing
comb.string.format("%4j", [{a : "b"}]) // '{\n    "a": "b"\n}'

```

String interpolation

```
comb.string.format("{hello}, {world}", {hello : "Hello", world : "World"); //"Hello, World";
comb.string.format("{[.2]min}...{[.2]max}", {min: 1, max: 10}); //"1.00...10.00"
```

@param {String} str the string to format, if you want to use a spacing character as padding (other than \\s) then put your format in brackets.
<ol>
<li>String Formats %[options]s</li>
<ul>
<li>- : left justified</li>
<li>Char : padding character <b>Excludes d,j,s</b></li>
<li>Number : width</li>
</ul>
</li>
<li>Number Formats %[options]d</li>
<ul>
<li>`-` : left justified</li>
<li>`+` or `<space>` : signed number if space is used the number will use a extra `<space>` instead of a `+`</li>
<li>`<Char>` : padding character <b>Excludes d,j,s</b></li>
<li>`Number` : width</li>
<li>`.Number`: specify the precision of the number</li>
</ul>
</li>
<li>Object Formats %[options]j</li>
<ul>
<li>Number : spacing for object properties.</li>
</ul>
</li>
</ol>


@param {Object|Array|Arguments...} obj the parameters to replace in the string
if an array is passed then the array is used sequentially
if an object is passed then the object keys are used
if a variable number of args are passed then they are used like an array

@returns {String} the formatted string
@memberOf comb.string
@static
Formats a string with the specified format