TL;DR
/**
*
* @param {string} str
* @param {...any} values
* @returns
*/
function format(str, ...values) {
if (typeof str !== "string" || str instanceof String) {
return false;
}
let re = /\{(\w+)\}/g; // match curl bracket and value inside
let replaceWith = [...values]; // get a copy
let allCurly = str.match(re) || []; // get all curl bracket
for (let i = 0; i < allCurly.length; i++) { // loop through the curl bracket
str = str.replace(allCurly[i], replaceWith[i]); // replace them in str
}
return str;
}
console.log(format("{a} {b} {d}", "daniel", "codex", "it's somthing"));
console.log(format("{a} something really cool", "daniel"));
console.log(format("{something}", "daniel"));
console.log(format("{1} {wow} {3}", "daniel", "codex", "something"));
console.log(format("{1} {2} {3}", 1, 2, 3));
console.log(format("{1}", "hello"));
Explanation
So format string in python is written as follows:
name = "daniel"
lname = "sparrow"
res = "{} {}".format(name, lname)
print(res) # daniel sparrow
We are going to make something like this.
Here is how it’s going to look like.
format("{a} {b}", "daniel", "codex")
// daniel codex
so it’s a bit different than python version 😅
First of all for us will be a function but for python it’s string method.
And for python have a lot more feature which u can check them out here 👇
https://www.programiz.com/python-programming/methods/string/format
Our function parameter will look like this:
format(str, ...values)
In str
we are going to have string with placeholder in {a}
or {1}
format.
And we have ...values
. in this blog i am not going to talk about rest parameter, if you like to learn more read this article. basically we use rest parameter in the case that user want to use more than one arguments.
So What’s the idea? there would always be some unique values (let’s call them placeholder) in the string in the form of {a}
or {1}
our job is to replace it with values.
Here is how the regex will look like 👇
let re = /\{(\w+)\}/g;
let allCurly = str.match(re) || [];
With this code we are going to find all of the placeholder, and if we can not find them we will return []
(that’s what the || []
do)
Also we get the copy of our value (because i don’t like mutate stuff):
let replaceWith = [...rest]
Then we have to loop through all of the allCurly
and replace it with replaceWith
with the helps of replace
method.
for (let i = 0; i < allCurly.length; i++){
str = str.replace(
allCurly[i],
replaceWith[i]
)
}
That’s how you get something similar to python format string in JS.
Challenge
How about a challenge?
- Right now what we just implement is a function, how about making it a string method?
Hint: you have to use something like this 👇
String.prototype.format = function() {
//
}
2. The problem with regex is that, we can write expression between placeholder like {str.toUpperCase()}
, can you find a way to run an expression?
I don’t know how to do that myself, if you did figure it out let me know @Daniel_Codex
Inspiration
I found a really interesting tweet by @betterways_dev. His solution also is really interesting.
Make sure to check his blog.