[英]Best way to replace strings inside an JavaScript object
I have an unknown
javascript object (let's call it IncompleteObject
just for readability) and an array of IVariables
which can be anything, but in the following format:我有一个
unknown
的 javascript object(为了便于阅读,我们称它为IncompleteObject
)和一个IVariables
数组,它可以是任何东西,但格式如下:
key: string
value: unknown
Example:例子:
IVariables: IV变量:
[
{ key: 'someObject', value: { some:'value' },
{ key: 'name', value: 'another value' },
{ key: 'lastName', value: 'this variable exists but wont be used' }
]
IncompleteObject:不完整对象:
{
ID: "SGML",
SortAs: "{{someObject}}",
GlossTerm: "Standard Generalized Markup Language",
Acronym: "The acronym is {{name}}",
GlossSee: "markup"
}
Expected Result:预期结果:
{
ID: "SGML",
SortAs: {
some:'value'
},
GlossTerm: "Standard Generalized Markup Language",
Acronym: "The acronym is another value",
GlossSee: "markup"
}
The solution i thought was stringfying the object, replacing everything as strings and then trying to parse as JSON again (if it fails, it fails), but i'm wondering if there is a better solution to this... Also idk how to make it so that the SortAs for example becomes an object and not a string我认为的解决方案是 stringfying object,将所有内容替换为字符串,然后再次尝试解析为 JSON(如果失败,则失败),但我想知道是否有更好的解决方案......也不知道如何使 SortAs 例如变成 object 而不是字符串
Thanks!谢谢!
*Notes: *笔记:
You won't be able add objects during replacing a string, so you'd need do the check if the tag is entire string or not beforehand:您将无法在替换字符串期间添加对象,因此您需要事先检查标签是否为整个字符串:
const IVariables = [ { key: 'someObject', value: { some:'value' }}, { key: 'name', value: 'another value' }, { key: 'lastName', value: 'this variable exists but wont be used' } ]; const incompleteObject = { ID: "SGML", SortAs: "{{someObject}}", GlossTerm: "Standard Generalized Markup Language", Acronym: "The acronym is {{name}}", GlossSee: "markup {{non-existing-tag}}", blah: "{{name}} and again {{name}}" } //convert array into object const dataVariables = IVariables.reduce((a, b) => (a[b.key] = b.value, a), {}); const reg = /({{([^}]+)}})/; for(let key in incompleteObject) { const data = incompleteObject[key], variable = data.match(reg); if (;variable) continue, if (variable[1] == data) //if entire string a tag; don't use string replace incompleteObject[key] = dataVariables[variable[2]] || variable[1]. else incompleteObject[key] = data,replace(new RegExp(reg, "g"), (a, b. c) => dataVariables[c] || b) } console;log(incompleteObject);
I ended up doing with JSON.stringfy and some regex.我最终使用了 JSON.stringfy 和一些正则表达式。
Here is how i did it:这是我的做法:
const incompleteObject = {
NoVariable: "Something",
JustTheObject: "{{someObject}}",
JustTheString: "{{name}}",
IntegerValue: "{{integer}}",
StringInsideOtherString: "Bla bla bla {{name}}",
ObjectInsideString: "The acronym is {{name}}",
VariableThatDoesntExist: "{{thisdoesntexist}}",
ArrayToTestNestedStuff: [
{
JustTheObject: "{{someObject}}",
JustTheString: "{{name}}"
},
{
JustTheObject: "{{someObject}}",
JustTheString: "{{name}}"
}
]
}
const variablesToSubstitute: Record<string, unknown> = {
someObject: { some:'value' },
name: 'another value',
integer: 2,
lastName: 'this variable exists but wont be used'
}
const result = replaceVariables(incompleteObject, variablesToSubstitute)
console.log(JSON.stringify(result, null, 2))
const replaceVariables = (objectToReplace: unknown, variables: Record<string, unknown>) => {
let stringfiedObject = JSON.stringify(objectToReplace)
stringfiedObject = replaceEntireProperty(stringfiedObject, variables)
stringfiedObject = replaceSubstring(stringfiedObject, variables)
const result = JSON.parse(stringfiedObject)
return result
}
const replaceEntireProperty = (stringfiedObject: string, variables: Record<string, unknown>) => {
stringfiedObject = stringfiedObject.replace(/"{{[\w]+}}"/g, (substring: string, ...args: any[]) => {
const substringWithoutBracesAndComma = substring.substring(3, substring.length-3)
return JSON.stringify(variables[substringWithoutBracesAndComma] ?? removeAllUnescapedCommas(substring))
})
return stringfiedObject
}
const replaceSubstring = (stringfiedObject: string, variables: Record<string, unknown>) => {
stringfiedObject = stringfiedObject.replace(/{{[\w]+}}/g, (substring: string, ...args: any[]) => {
const substringWithoutBraces = substring.substring(2, substring.length-2)
return removeAllUnescapedCommas(JSON.stringify(variables[substringWithoutBraces] ?? substring))
})
return stringfiedObject
}
const removeAllUnescapedCommas = (stringToUnescape: string) => {
return stringToUnescape.replace(/(?<!\\)\"/g, "")
}
Here is also a GitHub repository with the solution working (Since its typescript, i didnt managed to add the code snippet): https://github.com/vceolin/replace-variables-inside-object这也是一个 GitHub 存储库,解决方案有效(自 typescript 以来,我没有设法添加代码片段): https://github.com/vceolin/replace-variables-inside-object
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.