Skip to content

Instantly share code, notes, and snippets.

@z11i
Last active November 28, 2020 07:26
Show Gist options
  • Save z11i/febd9fe2bfd499db40d3a17327db532c to your computer and use it in GitHub Desktop.
Save z11i/febd9fe2bfd499db40d3a17327db532c to your computer and use it in GitHub Desktop.
Replaces all regular expression patterns in a string with dynamic data from a map.
function makeReplacer(str) {
const regex = /\$\w+\.(\w+)/g;
let strFragments = []; // stores static strings, or a function to get value from map
let m; // regex match object
let idx; // index tracking the position of one match in `str`
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
strFragments.push(str.substring(idx, m.index))
strFragments.push(
(key => {
return map => map[key]
})(m[1])
) // needs two lambdas, because we are passing m[1] as value to the inner lambda
idx = m.index + m[0].length
}
if (idx < str.length) {
strFragments.push(str.substring(idx))
}
return (varMap) => {
return strFragments.map(sf => {
if (typeof sf === 'string') {
return sf
}
return sf(varMap)
}).join('')
};
}
const str = `value $data.num1 + $data.num2 = $data.sum, right?`;
let replacer = makeReplacer(str)
let varMap = {
num1: 1,
num2: 2,
sum: 3,
}
console.log(replacer(varMap))
varMap['sum'] = 4
console.log(replacer(varMap))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment