admin管理员组文章数量:1244410
I have a template in a String and I want to replace a few of the placeholders with the values that I have in another string. For every placeholder that I replace, I also want to insert a break tag.
For eg if #ADDRESS2#
is found in the template, I am using the following code to replace all its occurrences with value in string val.address2
.
template_html = template_html.replace(/#ADDRESS2#/g, '<br />'+ val.address_2);
However there are scenarios when the string val.address2
is empty. In that case, I do not want to insert the break tag.
So I changed my code as follows
if( val.address_2.length > 0 ) {
template_html = template_html.replace(/#ADDRESS2#/g, '<br />'+ val.address_2);
} else {
template_html = template_html.replace(/#ADDRESS2#/g, '');
}
Is there a better way to write the above code as I have multiple Placeholders and for each Placeholder I have to write the code 2 times.
I have a template in a String and I want to replace a few of the placeholders with the values that I have in another string. For every placeholder that I replace, I also want to insert a break tag.
For eg if #ADDRESS2#
is found in the template, I am using the following code to replace all its occurrences with value in string val.address2
.
template_html = template_html.replace(/#ADDRESS2#/g, '<br />'+ val.address_2);
However there are scenarios when the string val.address2
is empty. In that case, I do not want to insert the break tag.
So I changed my code as follows
if( val.address_2.length > 0 ) {
template_html = template_html.replace(/#ADDRESS2#/g, '<br />'+ val.address_2);
} else {
template_html = template_html.replace(/#ADDRESS2#/g, '');
}
Is there a better way to write the above code as I have multiple Placeholders and for each Placeholder I have to write the code 2 times.
Share Improve this question edited Aug 13, 2019 at 14:21 Cerbrus 72.9k19 gold badges136 silver badges150 bronze badges asked Aug 13, 2019 at 13:58 ascsoftwascsoftw 3,4762 gold badges16 silver badges23 bronze badges 5- 2 Since jQuery is (primarily) a DOM manipulation library, it's not really relevant here. I've removed that tag. – Cerbrus Commented Aug 13, 2019 at 14:22
- why not use same template strings in the text and in the objects. it makes it easier to just replace with the same string. – Nina Scholz Commented Aug 13, 2019 at 14:22
- 1 Can you show more of those "multiple Placeholders" that you have? E.g. are they all quite regular or not, and how do they relate to the property names used for the replacement? – Peter B Commented Aug 13, 2019 at 14:40
- @nina yes, I can change the template to have same name as string. – ascsoftw Commented Aug 13, 2019 at 15:03
- @peter other vplaceholders are like City, State, zip. I can make the placeholder name same as object if that helps – ascsoftw Commented Aug 13, 2019 at 15:05
7 Answers
Reset to default 13Use a regex replacement, to which you pass a function.
That function will get the replacement keys as input, and depending on if there's a replacement available, it will insert a empty string, or the replacement with a linebreak:
const template = "#foo# this bla bla #bar# but #baz# and stuff";
const replacements = {
foo: "test",
bar: "",
baz: "not empty"
};
const result = template.replace(/#([^#]+)#/g, (match, key) => {
// If there's a replacement for the key, return that replacement with a `<br />`. Otherwise, return a empty string.
return replacements[key] !== undefined
? "<br />" + replacements[key]
: "";
});
console.log("template:", template);
console.log("result:", result);
The only "gotcha" here is that the keys in the template string have to match the keys in your replacements object. That's not necessarily a bad thing, though, as it would make it slightly more intuitive if you'd look back at your code later on.
The regex may look intimidating, but it's really quite simple:
/#([^#]+)#/g
/
: The start of the regex,#
: Literally the#
character,(
: The start of a capturing group,[^#]+
Any character that isn't a#
. The+
makes sure it matches as many as possible,)
: The end of a capturing group,#
: Literally the#
character,/g
: The end of the regex.g
is the global flag, so it doesn't stop at the first result.
The capturing group basically tells the regex to group everything that's between the brackets. The groups are then returned individually.
Perhaps you meant this?
var val = {
"address_1": "Address 1",
"address_2": "",
"address_10": "Address 10",
}
var template_html = `My address is #ADDRESS1# delivery address is #ADDRESS2# and billing is #ADDRESS10#`
template_html = template_html.replace(/#ADDRESS(\d+)#/g, function(addr, num) {
var str = val["address_"+num]; return str?str+"<br/>":""
})
console.log(template_html)
If the same logic should be applied for multiple address fields, then you might benefit from a helper function:
template_html = template_html
.replace(/#CITY1#/g, PrefixBrIfNotEmpty(val.city_1))
.replace(/#CITY2#/g, PrefixBrIfNotEmpty(val.city_2))
.replace(/#CITY3#/g, PrefixBrIfNotEmpty(val.city_3))
.replace(/#ADDRESS1#/g, PrefixBrIfNotEmpty(val.address_1))
.replace(/#ADDRESS2#/g, PrefixBrIfNotEmpty(val.address_2))
.replace(/#ADDRESS3#/g, PrefixBrIfNotEmpty(val.address_3));
function PrefixBrIfNotEmpty(str) {
return str ? '<br />' + str : '';
}
You can use ternary operator (empty string evaluates to false)
template_html = template_html.replace(/#ADDRESS2#/g, val.address_2 ? '<br />'+ val.address_2 : '');
The simplest change is to use the ternary operator like this:
template_html = template_html.replace(/#ADDRESS2#/g, ( val.address_2.length > 0 ) ? '<br />'+ val.address_2 : '');
Still not particularly elegant but a bit shorter than the original.
You could take the value with a check.
template_html = template_html.replace(
/#ADDRESS2#/g,
val.address_2 && '<br />' + val.address_2
);
For more than one placeholder, you could take a dynamic approach and use same pattern for the search and replacements.
var val = { address_2: 'foo', country_1: 'bar' }
template_html = 'Address: #ADDRESS2#\nCountry: #COUNTRY1#\nnothing: #NOTHING#'
template_html = template_html.replace(
/#([^#]+)#/g,
(_, group) => {
var key = group.match(/^(\D+)(\d*)$/).slice(1).map(s => s.toLowerCase()).join('_');
return (val[key] || '') && '<br />' + val[key];
}
);
console.log(template_html);
For getting a smarter replacement, yoou could take the idea of same strings as tempate and for getting the data from an object. In this case, take the replacement value and take this as key for the object or take an empty string for unknown values.
var val = { ADDRESS2: 'foo', COUNTRY1: 'bar' }
template_html = 'Address: #ADDRESS2#\nCountry: #COUNTRY1#\nnothing: #NOTHING#'
template_html = template_html.replace(
/#([^#]+)#/g,
(_, key) => (val[key] || '') && '<br />' + val[key]
);
console.log(template_html);
You mean, something like this:
template_html = template_html.replace(/#ADDRESS(\d+)#/g, function(address, number) {
return val.hasOwnProperty('address_' + number)
? '<br />' + val['address_' + number]
: '';
};
You should use the val.hasOwnProperty
just in case that val.['address_' + number]
contains a value like 0
, false
, ''
, undefined
, NaN
or other falsy values.
It makes sure the value is displayed anyway, because an undefined
isn't the same as not having the property at all.
It also avoids to get a value from the prototype, just in case.
This is based on mplungjan's answer.
If this is undesirable, and you only want to show strings, try this:
template_html = template_html.replace(/#ADDRESS(\d+)#/g, function(address, number) {
return val.hasOwnProperty('address_' + number)
&& val['address_' + number].length
&& (
(typeof val['address_' + number]) === 'string'
|| val['address_' + number] instanceof String
)
? '<br />' + val['address_' + number]
: '';
};
All of this checking ensures that it is a non-empty string (or String
instance, because new String()
returns a string object).
Checking if it is an instance of String
prevents issues due to typeof new String()
returning object
.
Arrays and array-like objects have a length
attributes (e.g.: jQuery instance, NodeList, {length: 1}
, [0]
and similars), but you dont want to show them as strings.
本文标签: Javascript ReplaceDynamic Value of ReplacementStack Overflow
版权声明:本文标题:Javascript Replace - Dynamic Value of Replacement - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740221353a2243871.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论