0

I am trying to create a RegExp with a specific variable, which matches the variable exactly and replaces all possible occurrences. I found some different answers here but they do not seem to work with my problem.

This is my code:

for(var translation in translations) {
  var regex = new RegExp("^" + translation + "$");
  htmlContent = htmlContent.replace(regex, translations[translation][lang]);
} 

"translations" is a JSON which looks like this:

{
"report_a_return-placeholder": {
    "de": "Rücksendung melden",
    "en": "Report a return",
    "nl": "rapporteer een terugkeer",
    "fi": "raportoi palautuksesta",
    "da": "rapportere et afkast",
    "no": "rapporter en retur",
    "sv": "rapportera en avkastning"
  }
}

And I am replacing inside the html:

<div id="Report_a_return">
    <span>report_a_return-placeholder</span>
</div>

When I try creating the regex without the anchors, everything works fine and the regex replaces. However, I have some translations which start similarly so the regex replaced them even though it was not an exact match. That's why I need anchors. But when doing it like above, nothing is replaced!

Edit:

to clarify with a better example. I have the problem that e.g. "pay-placeholder" and "cofirm_and_pay-placeholder" both match "confirm_and_pay-placeholder". But I want "pay-placeholder" to only match "pay-placeholder" and "confirm_and_pay-placeholder" to match only that. That doesnt work rn. (if I just use newRexExp('pay-placeholder') this matches also the string "confirm_and_pay-placeholder")

threxx
  • 1,143
  • 1
  • 23
  • 49
  • In the perfect world, this is done inside the HTML template Before it's rendered, not after. The problem that you have is that `^` and `$` look for the beginning and the end of the string, which does not apply to the HTML. I would search for `'' + translation + ''` instead if you do need the regexp. But less prone to fail would be to actually select the div by id and then replace its child spans innerText with translation instead of using regexp. – Shilly May 28 '19 at 12:06

1 Answers1

1

Your ^ character tells the regex that it should match from the beginning of the string and your $ tells to match to the end of the string.

That means your regex only works for a string like report_a_return-placeholder and nothing more. Remove both of the characters and everything will be fine.

I love using regex.com to check what is happening and get a full reference of regular expressions.

regexr.com example

This one could work for you as long as there is one translation string per tag.

var translations = {'pay_placeholder': 'FooBar'}
var translation = 'pay_placeholder'
var regex = new RegExp('(<\\w+>)(' + translation + ')(<\\/\\w+>)')

var match = '<span>pay_placeholder</span>'.replace(regex, (match, p1, p2, p3, offset, str ) => {
    return p1 + translations[p2] + p3
})

var didntMatch = '<span>confirm_and_pay_placeholder</span>'.replace(regex, (match, p1, p2, p3, offset, str ) => {
    return p1 + translations[p2] + p3
})

console.log(match, didntMatch)
coderocket
  • 574
  • 3
  • 11
  • yes but I have the problem that e.g. "confirm-placeholder" and "cofirm_and_pay-placeholder" both match "confirm_and_pay-placeholder". But I want "confirm-placeholder" to only match "confirm-placeholder" and "confirm_and_pay-placeholder" to match only that. That doesnt work with that solution – threxx May 28 '19 at 12:14
  • Try it with regexr.com. They both should only match once not twice. `const regex = new RegExp('confirm_placeholder') const match = 'confirm_placeholder confirm_other_placeholder'.match(regex) console.log(match)` This only matches once for the first confirm-placeholder. – coderocket May 28 '19 at 12:18
  • "confirm_and_pay-placeholder" is matched by "pay-placeholder" and by "confirm_and_pay-placeholder". I checked with regex101 – threxx May 28 '19 at 12:21
  • 1
    Edited my answer. You should use an i18n library instead of creating your own translation logic. This would be easier. – coderocket May 28 '19 at 12:50