Reputation: 283
Working example: http://alpha.jsfiddle.net/gTpWv/
Both of the methods work separately, but once regexp for smilies gets raw HTML code to process, things get ugly.
K = K.replace(/\b((http:\/\/)|(www\.))[^ ]{5,}/g, function (x) {
var b = x;
if (b.indexOf("www") == 0) {
b = "http://" + b
}
return '<a href="' + b + '" target="_blank">' + x + "</a>"
// K is now /"Testing <a href="http://www.google.com," target="_blank">http://www.google.com,</a> :D, ^^"/
for (var d = 0; d < smiliesArray.length; d++) {
K = K.replace(new RegExp(smiliesArray[d][0], "g"), '<img src="' + smiliesArray[d][1] + '">');
}
// K is now Testing <a href="http%3Cimg%20src=" http:="" i.imgur.com="" mvk87.gif"="">/www.google.com," target="_blank">http<img src="http://i.imgur.com/MVk87.gif">/www.google.com,</a> <img src="http%3Cimg%20src=" http:="" i.imgur.com="" mvk87.gif"="">/i.imgur.com/7JJNL.gif">, <img src="http%3Cimg%20src=" http:="" i.imgur.com="" mvk87.gif"="">/i.imgur.com/vRgA3.gif">
I did find regexp claiming to solve this issue, but inserting it into the regexp: http://alpha.jsfiddle.net/gTpWv/1/ returns nothing.
I've also found interesting the idea to follow this procedure, but I would be left with two seperate lines, one with links and one with smilies and it would take another regexp to inject one into another.
I'm not sure should I meddle with a better regexp(s) or try to find another way to solve this problem.
Upvotes: 1
Views: 540
Reputation: 7199
The problem is that :/
will be caught in places where it shouldn't. Every time K
changes during replaces, it is fed with some http://
strings that contain the seeds of evil... the :/
bits. At the next iteration, these will be replaced with the corresponding smilie, corrupting the generated HTML stored in
K
.
My approach was to do a 2-phase search and replace. See it in action here http://alpha.jsfiddle.net/gTpWv/7/, and read on for further explanation.
We start by changing every url and smilie to intermediate forms. To use your example string "Testing www.google.com, :D, ^^ :/"
:
$each(N.split("\n"), function(K) {
// First pass: creating url and smilie maps
var urlSubstitutions = [];
var smilieSubstitutions = [];
K = K.replace(/\b((http:\/\/)|(www\.))[^ ]{5,}/g, function(match) {
var b = match;
if (b.indexOf("www") == 0) {
b = "http://" + b
}
urlSubstitutions.push({ anchor: match, url: b });
return "{{_u_" + urlSubstitutions.length + "_}}";
});
for (var d = 0; d < smiliesArray.length; d++) {
K = K.replace(new RegExp(smiliesArray[d][0], "g"), function(x){
smilieSubstitutions.push({ smilie: x, image: smiliesArray[d][1] });
return "{{_s_" + smilieSubstitutions.length + "_}}";
});
}
By now, K will contain Testing {{_u_1_}} {{_s_1_}}, {{_s_2_}} {{_s_3_}}. I hope it's clear that these {{}} strings are the aforementioned intermediate forms of urls and smilies. The actual values of these strings are stored in two arrays named urlSubstitutions
and smilieSubstitutions
. The next step is simply to decode the intermediate forms into their formatted versions:
// Second pass: applying urls and smilies
K = K.replace(/{{_u_(\d+)_}}/g, function(match, index) {
var substitution = urlSubstitutions[parseInt(index)-1];
return '<a href="' + substitution.url + '" target="_blank">' + substitution.anchor + "</a>";
});
K = K.replace(/{{_s_(\d+)_}}/g, function(match, index) {
var substitution = smilieSubstitutions[parseInt(index)-1];
return '<img src="' + substitution.image + '">';
});
document.write(K)
});
Hope it helps!
Upvotes: 2