271
s = 'hello %s, how are you doing' % (my_name)

That's how you do it in python. How can you do that in javascript/node.js?

5

16 Answers 16

517

With Node.js v4 , you can use ES6's Template strings

var my_name = 'John';
var s = `hello ${my_name}, how are you doing`;
console.log(s); // prints hello John, how are you doing

You need to wrap string within ` (backtick) instead of ' (apostrophe)

Sign up to request clarification or add additional context in comments.

10 Comments

Plus 1 Because we are in 2017 and ES6 is basically standard in the node world.
This is now (2017) the correct answer. Be aware that you will need Babel in your toolchain to support older browsers.
I've suggested to the node.js developers that it would be really useful to make it clear on pages such as nodejs.org/api/readline.html that it is a backtick. There was an issue for it here: github.com/nodejs/docs/issues/55
Fell for the backticks trap myself, thanks for the comment ;)
What if my string is a part of configuration file hello ${my_name}, how are you doing and I want to assign variable dynamically after reading string from config?
|
199

Note, from 2015 onwards, just use backticks for templating

let a = `hello ${name}`    // NOTE!!!!!!!! ` not ' or "

Note that it is a backtick, not a quote.


If you want to have something similar, you could create a function:

function parse(str) {
    var args = [].slice.call(arguments, 1),
        i = 0;

    return str.replace(/%s/g, () => args[i++]);
}

Usage:

s = parse('hello %s, how are you doing', my_name);

This is only a simple example and does not take into account different kinds of data types (like %i, etc) or escaping of %s. But I hope it gives you some idea. I'm pretty sure there are also libraries out there which provide a function like this.

7 Comments

That's basically the best you'll get since it's not supported directly by the language as it is in python.
The other answer, that features util.format(), should be the accepted answer... though preferably it would also mention ES6's template strings (which admittedly didn't exist in 2011). We really should be able to wiki-hijack old questions to keep them updated. :\
This is nice, the template literals aren't exactly same thing
I had an issue while using "arguments". When multiple clients passed from the parse, the "str" was mixed up. Any explanation?
@tspentzas: I don't know what "When multiple clients passed from the parse" is supposed to mean.
|
65

if you are using ES6, the you should use the Template literals.

//you can do this
let sentence = `My name is ${ user.name }. Nice to meet you.`

read more here.

Comments

48

util.format does this.

It will be part of v0.5.3 and can be used like this:

var uri = util.format('http%s://%s%s', 
      (useSSL?'s':''), apiBase, path||'/');

1 Comment

Nice, thanks for the tip! console.log('%s', value) also should work.
45

As of node.js >4.0 it gets more compatible with ES6 standard, where string manipulation greatly improved.

The answer to the original question can be as simple as:

var s = `hello ${my_name}, how are you doing`;
// note: tilt ` instead of single quote '

Where the string can spread multiple lines, it makes templates or HTML/XML processes quite easy. More details and more capabilitie about it: Template literals are string literals at mozilla.org.

1 Comment

"tilt ` instead of single quote '" you save may day :)
25

Do that:

s = 'hello ' + my_name + ', how are you doing'

Update

With ES6, you could also do this:

s = `hello ${my_name}, how are you doing`

2 Comments

What do you mean "Its not possible" ? :? If you like to have formated text you can do it as described above by Felix Kling. This is the best answer as I see here ;) :)
@TIMEX It's possible just give it a try.
8

I wrote a function which solves the problem precisely.

First argument is the string that wanted to be parameterized. You should put your variables in this string like this format "%s1, %s2, ... %s12".

Other arguments are the parameters respectively for that string.

/***
 * @example parameterizedString("my name is %s1 and surname is %s2", "John", "Doe");
 * @return "my name is John and surname is Doe"
 *
 * @firstArgument {String} like "my name is %s1 and surname is %s2"
 * @otherArguments {String | Number}
 * @returns {String}
 */
const parameterizedString = (...args) => {
  const str = args[0];
  const params = args.filter((arg, index) => index !== 0);
  if (!str) return "";
  return str.replace(/%s[0-9]+/g, matchedStr => {
    const variableIndex = matchedStr.replace("%s", "") - 1;
    return params[variableIndex];
  });
}

Examples

parameterizedString("my name is %s1 and surname is %s2", "John", "Doe");
// returns "my name is John and surname is Doe"

parameterizedString("this%s1 %s2 %s3", " method", "sooo", "goood");
// returns "this method sooo goood"

If variable position changes in that string, this function supports it too without changing the function parameters.

parameterizedString("i have %s2 %s1 and %s4 %s3.", "books", 5, "pencils", "6");
// returns "i have 5 books and 6 pencils."

Comments

5

A few ways to extend String.prototype, or use ES2015 template literals.

var result = document.querySelector('#result');
// -----------------------------------------------------------------------------------
// Classic
String.prototype.format = String.prototype.format ||
  function () {
    var args = Array.prototype.slice.call(arguments);
    var replacer = function (a){return args[a.substr(1)-1];};
    return this.replace(/(\$\d+)/gm, replacer)
};
result.textContent = 
  'hello $1, $2'.format('[world]', '[how are you?]');

// ES2015#1
'use strict'
String.prototype.format2 = String.prototype.format2 ||
  function(...merge) { return this.replace(/\$\d+/g, r => merge[r.slice(1)-1]); };
result.textContent += '\nHi there $1, $2'.format2('[sir]', '[I\'m fine, thnx]');

// ES2015#2: template literal
var merge = ['[good]', '[know]'];
result.textContent += `\nOk, ${merge[0]} to ${merge[1]}`;
<pre id="result"></pre>

Comments

5
var print = console.log;

function dformat(str, ...arr) {
  return str.replace(/%(\d+)/g, function(_,i) {
    return arr[--i];
  });
}

function wformat(str, dict) {
  return str.replace(/%(\w+)/g, function(_,k) {
    return dict[k];
  });
}

function sformat(str, dict) {
  return str.replace(/\$(\w+)/g, function(_,m) {
    return dict[m];
  });
}

function tformat(str, dict) {
  return str.replace(/\${(\w+)}/g, function(_,m) {
    return dict[m];
  });
}

print(1, dformat("uid:%1, name:%2", 120, "someone") )
print(2, wformat("color: %name", {name: "green"})   )
print(3, sformat("img: $url", {url: "#"})   )
print(4, tformat("${left} ${right}", {right:"1000", left: "7fff"}) )

Comments

4

Try sprintf in JS or you could use this gist

1 Comment

the diveintojavascript link is dead
4

If you are using node.js, console.log() takes format string as a first parameter:

 console.log('count: %d', count);

4 Comments

This is a good point, but the question is about string interpolation. console.log() only outputs the formatted string to STDOUT. In other words, you can't use the result of count: %d
FYI 2021 and this syntax is still very much supported!
@JimSchubert This is sorta string interpolation, it just has a very specific use case. I feel that, because the user asked for this syntax specifically, it was worth mentioning in an answer.
@NodeSamurai the question is how to put variables into strings. The console.log answer just shows how console.log supports string formatting as parameters, which may or may not work the same as other answers to the question.
3

const format = (...args) => args.shift().replace(/%([jsd])/g, x => x === '%j' ? JSON.stringify(args.shift()) : args.shift())

const name = 'Csaba'
const formatted = format('Hi %s, today is %s and your data is %j', name, Date(), {data: {country: 'Hungary', city: 'Budapest'}})

console.log(formatted)

Comments

2
var user = "your name";
var s = 'hello ' + user + ', how are you doing';

1 Comment

I see a couple of problems with that; it uses concatenation rather than string formatting which is a red flag for me when doing code reviews, as it's usually more difficult to read and maintain. Also you can't safely store that "pattern" in a retrieval system (like a config file or DB) and inject in the value of user later.
1

Here is a Multi-line String Literal example in Node.js.

> let name = 'Fred'
> tm = `Dear ${name},
... This is to inform you, ${name}, that you are
... IN VIOLATION of Penal Code 64.302-4.
... Surrender yourself IMMEDIATELY!
... THIS MEANS YOU, ${name}!!!
...
... `
'Dear Fred,\nThis is to inform you, Fred, that you are\nIN VIOLATION of Penal Code 64.302-4.\nSurrender yourself IMMEDIATELY!\nTHIS MEANS YOU, Fred!!!\n\n'
console.log(tm)
Dear Fred,
This is to inform you, Fred, that you are
IN VIOLATION of Penal Code 64.302-4.
Surrender yourself IMMEDIATELY!
THIS MEANS YOU, Fred!!!


undefined
>

2 Comments

It's called a template string, and you might want to just upvote this existing answer
This "template string" example that i have showed IS a "template string" that uses a Multi-line String Literal.
1

You can implement your own format function that takes a string and key-value pairs.

the function:

function format(str, args) {
    return str.replace(/%(\w+)/g, (_, key) => args[key]);
}
const message = "Hello, %name! How are you doing?";
const args = {
    name: "Alice"
};

const formattedMessage= format(message, args);

Comments

-1

I do it like this

String.prototype.format = function (...args) {
  return args.reduce((_str, val) => _str.replace(/%[0-9]\$s+/, val), this)
};

var format = "%1$s has %2$s messages".format("UserName", "50")

document.getElementById("demo").innerHTML = format;
<h2>Strin format</h2>

<p id="demo"></p>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.