Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a string formatter with variable names

I'd like to implement a string formatter. I've used formatters that take string like "the quick, brown {0} jumps over the lazy {1}" where you pass in parameters whose cardinal location is used to replace the braced integers. I'd love to be able to do something more like "the quick, brown {animal1} jumps over the lazy {animal2}" where animal1 and animal2 are variables and are simply evaluated. I got the following method implemented, but then realized that eval is not going to work because it doesn't use the same scope.

String.prototype.format = function() {
    reg = new RegExp("{([^{}]+)}", "g");
    var m;
    var s = this;
    while ((m = reg.exec(s)) !== null) {
        s = s.replace(m[0], eval(m[1]));
    }
    return s;
};
  1. Is there a way to do this without using eval (doesn't seem like it).
  2. Is there a way to give eval the closure so it gets scope? I tried with(window) and window.eval(), but that didn't work.
like image 314
Jeremy Foster Avatar asked Oct 08 '13 17:10

Jeremy Foster


People also ask

How do you format a variable name in string Python?

The placeholders inside the string module Python are defined in curly brackets, e.g., “Welcome to Guru99 {}”. format('value here'). The placeholder can be empty {}, or it can have a variable for e.g {name} , or it can have a number index e.g {0} , {1} etc.

How do you add a variable to a string?

In JavaScript, we can assign strings to a variable and use concatenation to combine the variable to another string. To concatenate a string, you add a plus sign+ between the strings or string variables you want to connect. let myPet = 'seahorse'; console.

Can you use .format on variables Python?

Python's str. format() method of the string class allows you to do variable substitutions and value formatting. This lets you concatenate elements together within a string through positional formatting.


2 Answers

For a usage like var result = "This will get formatted with my {name} and {number}".format({name: "TetsujinOni", number: 1234});

Why not head off in this direction:

String.prototype.format = function(scope) {
    reg = new RegExp("{([^{}]+)}", "g");
    var m;
    var s = this;
    while ((m = reg.exec(s)) !== null) {
        s = s.replace(m[0], scope[m[1]]);
    }
    return s;
};
like image 133
Tetsujin no Oni Avatar answered Sep 22 '22 11:09

Tetsujin no Oni


All global variables are defined in the window object, so you should be able to do this without eval:

String.prototype.format = function(scope) {
    scope = scope || window; //if no scope is defined, go with window
    reg = new RegExp("{([^{}]+)}", "g");
    var m;
    var s = this;
    while ((m = reg.exec(s)) !== null) {
        s = s.replace(m[0], scope[m[1]]);
        //                  ^^^^^^^^^^^
    }
    return s;
};

Here you should also simply be able to change window to what scope you feel like.

If variables are not in the global scope, but rather in your current scope, you might want to read this or go with Tetsujin's solution.

like image 42
h2ooooooo Avatar answered Sep 25 '22 11:09

h2ooooooo