Forum Moderators: open

Message Too Old, No Replies

JavaScript replace using 2 arrays for find & replace with g flag?

Finding all smiley text and replacing it with BBcode.

         

JAB Creations

2:24 am on Jan 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



What I'm trying to doing is taking chat room text and replacing smiley strings with BBcode.

The issue is that I'm know that using an array element for the find part of the replace method is not being applied as regex when I need it to in order to use the g (global) flag for instances where there is more then once instance of the same smiley.

So I know that using an array element is not working with regular expressions though I can't seem to find anything about it specifically, well probably not until I've told everyone and then I might figure it out on my own any way as things usually go. Thoughts please? Here's my code...

var smiley_array = [':)', ':p', ':d'];
var smiley_xhtml = ['happy', 'glee', 'big-grin'];

function smiley_convert(text)
{
for (var i in smiley_array)
{
var txt_new = ' '+path+'images/smiley_'+smiley_xhtml[i]+'.gif ';
var txt_return = text.replace(/smiley_array[i]/g, txt_new);
}
return txt_return;
}

astupidname

10:13 am on Jan 14, 2010 (gmt 0)

10+ Year Member



Best way to go about it would be to forego the array for a translation object and a pre-defined regex which both match all possible smiley's.
So I guess I would go about it like (add more smiley's/emoticons/whatever):

<script type="text/javascript">

function smiley_convert(text, path) {
var smileyTranslator = {
":)" : "happy",
":p" : "glee",
":d" : "big-grin"
};
var smileyRegex = /:\)¦:p¦:d/g; //<-- NOTE: you may need to replace the 'or' conditionals there if you copy and paste, as this forum tends to wreck the ¦ pipes
var converted = text.replace(
smileyRegex,
function (s) {
if (s in smileyTranslator) {
return '[img]'+ path +'images/smiley_'+ smileyTranslator[s] +'.gif[/img]';
}
return s;
}
);
return converted;
}

var aStringWithSmileys = 'Being :) makes you feel :p! :d The symbol :) means "happy", the symbol :p means "glee", the symbol :d means "big-grin"';

alert(aStringWithSmileys);
var aSmileyStringConverted = smiley_convert(aStringWithSmileys, 'http://www.example.com/');
alert(aSmileyStringConverted);

</script>

Fotiman

2:40 pm on Jan 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Does this work?

var txt_return = text.replace((new RegExp(smiley_array[i],"g")), txt_new);

JAB Creations

1:12 am on Jan 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for both your replies and I tried both sets of code.

Fotiman, it looked too elegant to work and threw a couple errors in Firefox's console of which after tinkering with I could not resolve.

ASN, I tried your code and I honestly never imagined one could throw an anonymous function inside of a method like that. JavaScript is pretty crazy like that!

So here is the full-fledged working version of the code after my own revisions, again thanks to you both!

- John

function smiley_convert(text)
{
var smileyTranslator =
{
'0:)' : 'angel',
':d' : 'big-grin',
':b' : 'blush',
'?(' : 'confused',
'c(' : 'crying',
'o.0' : 'disbelief',
':>' : 'dork',
'>)' : 'evil-grin',
':p' : 'glee',
':)' : 'happy',
':¦' : 'indifferent',
'8)' : 'joe-cool',
':lol' : 'laugh',
':l' : 'love',
':n' : 'nervous',
'n)' : 'nut',
'>__>' : 'paranoid',
':r' : 'reading',
':s' : 'spitting',
'o.o' : 'surprised',
'<.<^' : 'uncertain',
'-__-' : 'unimpressed',
'>:<' : 'vampire',
';)' : 'wink',
};
var smileyRegex = /0:\)¦:d¦:b¦\?\(¦c\(¦o.0¦:\>¦\>\)¦:p¦:\)¦:\¦¦8\)¦:lol¦:l¦:n¦n\)¦>__>¦:r¦:s¦o.o¦<.<\^¦-__-¦>:<¦;\)/g;
var converted = text.replace(smileyRegex,function (s) {if (s in smileyTranslator) {var img = '[img]'+path+'images/smiley_'+ smileyTranslator[s] +'.gif[/img]'; return img;} return s;});
return converted;
}

Fotiman

2:21 pm on Jan 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Ah, right. Mine would not work because you'd need to modify the values in smiley_array slightly. Because they are being passed as a string value to the RegExp, they need to be escaped properly. So you would have had to do something like this:

var smiley_array = [':\\)', ':p', ':d'];

And then my example would have worked. :)

astupidname

7:27 pm on Jan 15, 2010 (gmt 0)

10+ Year Member



would have worked. :)

Yeah, it would have, although another flaw in the original code would need fixing first also:
var txt_return = text.replace(/smiley_array[i]/g, txt_new);
}
return txt_return;

Re-defining txt_return with the var statement each loop there won't work right, needs to be:
<script type="text/javascript">

function smiley_convert(text, path) {
var smiley_array = [':\\)', ':p', ':d'];
var smiley_xhtml = ['happy', 'glee', 'big-grin'];
for (var i in smiley_array) {
var txt_new = ' '+path+'images/smiley_'+smiley_xhtml[i]+'.gif ';
text = text.replace(new RegExp(smiley_array[i], "g"), txt_new);
}
return text;
}

var aStringWithSmileys = 'Being :) makes you feel :p! :d The symbol :) means "happy", the symbol :p means "glee", the symbol :d means "big-grin"';
var converted = smiley_convert(aStringWithSmileys, 'http://www.example.com/');
alert(converted);

</script>

But, it kinda sucks to have to pervert the smiley_array. I found that the below will also work just fine:

<script type="text/javascript">

function smiley_convert(text, path) {
var smiley_array = ['0:)', ':d', ':b', '?(', 'c(', 'o.0', ':>', '>)', ':p', ':)', ':¦', '8)', ':lol', ':l', ':n', 'n)', '>__>', ':r', ':s', 'o.o', '<.<^', '-__-', '>:<', ';)'];
var smiley_xhtml = ['angel', 'big-grin', 'blush', 'confused', 'crying', 'disbelief', 'dork', 'evil-grin', 'glee', 'happy', 'indifferent', 'joe-cool', 'laugh', 'love', 'nervous', 'nut', 'paranoid', 'reading', 'spitting', 'surprised', 'uncertain', 'unimpressed', 'vampire', 'wink'];
//may be things left out yet in replacePattern... rush job,
//but should cover everything that could cause problems in a regex..., but beware this is just for demo anyhow:
var replacePattern = /(\)¦\(¦\?¦\!¦\.¦\[¦\]¦\{¦\}¦\¦¦\^¦\$¦\+¦\*¦\\¦\/)/g;
//note the replacePattern's source above is wrapped in parens: ( )
//so any match is captured and sent to RegExp $1
for (var i in smiley_array) {
var rexer = new RegExp(smiley_array[i].replace(replacePattern, '\\$1'), "g");
var txt_new = ' '+path+'images/smiley_'+smiley_xhtml[i]+'.gif ';
text = text.replace(rexer, txt_new);
}
return text;
}

var aStringWithSmileys = ' 0:) :d :b ?( c( o.0 :> >) :p :) :¦ 8) :lol :l :n n) >__> :r :s o.o <.<^ -__- >:< ;)';
//double it up to demo global capability:
aStringWithSmileys += '\n\n'+ aStringWithSmileys;
var converted = smiley_convert(aStringWithSmileys, 'http://www.example.com/');
alert(converted);

</script>


Remember, if you copy and paste the above, to carefully replace all the pipes-> ¦
[rant](Why must I always apologize for this forum wrecking them? I filed a bug report long time ago and I *know* the fix I think -somewhere on the back-end pipes are replaced with &#166; when they should be &#124; I believe. Could someone get on Engine's behind about it already? Or tell me why they must be wrecked?)[/rant]

But, ultimately, I personally prefer the 'translation object' as incorporated in OP's latest post, seems much cleaner and more easily maintained/added to/viewed to see what's what, no obvious loop, and pretty much 'a horse a piece' as far as bits used after removing comments etc.. Ya gotta love objects for organization though.

Fotiman

8:21 pm on Jan 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month




...although another flaw in the original code would need fixing first also:

Note, my solution was only addressing the original problem of doing the text replacement (I didn't really examine the other functionality, as it sounded like it was working for him). :)

As for the pipes, I'll pass along your complaint (I agree, it's a pet peeve of mine as well).

astupidname

8:45 pm on Jan 15, 2010 (gmt 0)

10+ Year Member



I'll pass along your complaint

=D>
:-bd

JAB Creations

9:49 pm on Jan 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'm now redoing my site's private messaging system though I will rework this a little as there is another function that shares the array and I'm going to try to minimize any bloat excessive bloat...not entirely sure.

ASN, this site is more of a work-horse then a show-pony and it seems to be run with that in mind.

I'll take a look at the code more closely a little later this weekend and report what I have. I have to any way because IE doesn't understand indexOf plus I have to make that script also give focus back to the text input field after clicking a smiley.

- John