SteeveDroz
SteeveDroz

Reputation: 6136

How can I use JSON keys as regex?

I would like to have the following JSON object:

let emotes = {
  /:-?\)/: 'smiley.png',
  /:-?\(/: 'sady.png',
  /:-?o/i: 'surprisey.png'
}

And I would like to replace the keys by the values in a text like this:

Object.keys(emotes).forEach(function(emote) {
  content = content.replace(emote, '<img src="smileys/' + emotes[emote] + '">')
})

This is not working. What is the correct way to do that?

Upvotes: 1

Views: 465

Answers (3)

nixkuroi
nixkuroi

Reputation: 2269

You can turn your "keys" into strings, which would make it a valid JSON object. Also, the syntax is Object.keys, instead of Objects.getKeys.

Check out the working snippet below.

let emotes = {
  ":-?)" : 'smiley.png',
  ":-?(": 'sady.png',
  ":-?o": 'surprisey.png'
}

var content = "  :-?)   :-?(  :-?o";

Object.keys(emotes).forEach(function(emote) {
  content = content.replace(emote, '<img src="smileys/' + emotes[emote] + '">')
})
console.log(content);

Upvotes: 1

Pointy
Pointy

Reputation: 413727

Personally I would use an array. That allows you to use regex constants and avoid constructing RegExp instances from strings, and it also would guarantee the application order:

let emotes = [
  [ /:-?\)/, 'smiley.png' ],
  [ /:-?\(/, 'sady.png' ],
  [ /:-?o/i, 'surprisey.png' ]
];

Then:

emotes.forEach(function(pair) {
  content = content.replace(pair[0], '<img src="smileys/' + pair[1] + '">');
});

You could use an array of objects if you didn't want the (slight, in my opinion, but to each his own) ugliness of the numeric indexes:

let emotes = [
  { pattern: /:-?\)/, src: 'smiley.png' },
  { pattern: /:-?\(/, src: 'sady.png' },
  { pattern: /:-?o/i, src: 'surprisey.png' }
];

Upvotes: 4

ShadowRanger
ShadowRanger

Reputation: 155418

To be clear, that's not a JSON object. It's not even a legal JavaScript object literal. JS objects are keyed by string, not regex. What you've done isn't legal in Firefox AFAICT, possibly other browsers. Check your browser logs, it's likely rejecting your definition of emotes entirely.

If you want to have a bunch of pairs to work with, make an array of pairs and use that:

let emotes = [
  [/:-?\)/, 'smiley.png'],
  [/:-?\(/, 'sady.png'],
  [/:-?o/i, 'surprisey.png'],
]

emotes.forEach(function(emotereplacement) {
    var [emote, replacement] = emotereplacement;
    content = content.replace(emote, '<img src="smileys/' + replacement + '">');
});

Upvotes: 2

Related Questions