Reputation: 401
I'm working on a project on search about emoji
and replace
it with icon
but I have some problem on regular expression
, Below mentioned is my code for reference:
var f = ["( :3 )" , "( :P )","\(:star:\)"];
var re = function(s){return new RegExp(s, 'g');};
now when I'm going to search about emoji
and replace
it as shown below:
s = "hello :D how are you :P dwdwd";
for(var n in f){
var m;
if ((m = re(f[n]).exec(s)) !== null) {
m.forEach((match, groupIndex) => {
s = s.replace(match,"<img src='http://abs.twimg.com/emoji/v1/72x72/"+ r[n] +".png'>");
});
}}
In this case, it works well and replace the emoji
. But it only replace when there are space before and after emoji
what should i do to replace the emoji
in the begin of string or end !
s = ":D hello how are you :)";
This case is not working. How can i edit my regular expression
for being able to replace emoji
at begin and end of string and at the same time if its found in middle of string & have space between word and emoji
My 2nd problem with regular expression
is "\(:star:\)"
it never replaces. While it must replace word :star:
with an emoji
but i think i miss some thing on regular expression
for it.
Upvotes: 1
Views: 151
Reputation: 50787
I created a more generic solution, starting with the mapping of emojis to the relevant names. Rather than two lists that need to be kept in synch, I used a single object:
const emojis = {
'(c)': 'a9',
'(r)': 'ae',
'(tm)': '2122'
//, ...
};
This strikes me as a much more useful structure to work with, but the code below could easily be altered to deal with the two-lists version.
Then I use a helper function to escape characters which are not allowed as plain text in Regular Expression by prepending them with \
:
const escapeSpecials = (() => {
const specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
const reg = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
return str => str.replace(reg, '\\$1');
})();
Then I have the key function:
const replaceStringsWith = (emojis, convert) => str => Object.keys(emojis).reduce(
(str, em) => str.replace(new RegExp(`(^|\\s+)(${escapeSpecials(em)})($|\\s+)`, 'g'),
(m, a, b, c) => `${a}${convert(emojis[b], b)}${c}`),
str
);
This takes an object containing string/replacement pairs and a converter function which accepts the replacement and gives you back the final form. It returns a function which takes a string, and then searches for any matches on the keys of the object (properly checked for strings or string ends), replacing them with the result of calling the converter on the object's value for the particular key.
Thus we can do:
const toUrl = (name) => `<img src='http://abs.twimg.com/emoji/v1/72x72/${name}.png'>`;
const replaceEmojis = replaceStringsWith(emojis, toUrl)
and call it as
const s = "This is Copyright (c) 2017, FooBar is (tm) BazCo (r)";
replaceEmojis(s); //=>
// `This is Copyright <img src='http://abs.twimg.com/emoji/v1/72x72/a9.png'>
// 2017, FooBar is <img src='http://abs.twimg.com/emoji/v1/72x72/2122.png'>
// BazCo <img src='http://abs.twimg.com/emoji/v1/72x72/ae.png'>`
Note that the converter also takes a second parameter. So you could instead use
const toUrl = (name, emoji) =>
`<img src='http://abs.twimg.com/emoji/v1/72x72/${name}.png' title='${emoji}'>`;
to get
//=> `This is Copyright <img
// src='http://abs.twimg.com/emoji/v1/72x72/a9.png' title='(c)'>
// 2017, FooBar is <img src='http://abs.twimg.com/emoji/v1/72x72/2122.png'
// title='(tm)'> BazCo <img src='http://abs.twimg.com/emoji/v1/72x72/ae.png' title='(r)'>"
Upvotes: 0
Reputation: 108
var content = "hello :D how are you :P dwdwd";
content = content.replace(/((:D|:P))/g,function(match){
var result = "";
var index = -1;
switch(match)
{
case ":D":
result = "happy";
index = 0
break;
case ":P":
result = "smilie";
index = 1
break;
}
if(index != -1)
{
return "<img src='http://abs.twimg.com/emoji/v1/72x72/"+index+".png'>";
}
return result;
});
console.log(content);
Please try this.
Upvotes: 0
Reputation: 5256
Just remove the spaces from your emoji regex.
var f = ["(:3)", "(:P)", "\(:star:\)"];
var r = ["[sadface]", "[toungeface]", "[staremoji]"];
var re = function(s) {
return new RegExp(s, 'g');
};
s = "hello :3 how are you :P dwdwd :star: :3";
console.log(s);
for (var n in f) {
var m;
if ((m = re(f[n]).exec(s)) !== null) {
m.forEach((match, groupIndex) => {
s = s.replace(match, r[n]);
});
}
}
console.log(s);
Upvotes: 0
Reputation: 2666
You can use beginning & ending anchors along with pipe to achieve this. For example:
/(^:3\s)|(\s:3\s)|(\s:3$)/g
^
is an anchor which matches :3\s
to the beginning of the string.
$
is an anchor which matches \s:3
to the end of the string.
\s
matches whitespace.
|
is the pipe operator which acts as a logical OR operator between the different capture groups.
Upvotes: 1