I know there are many arguments as to why this is a bad idea, but in my implementation I\'m planning on enabling/disabling bad words in the account settings. In other words
Something like this might work:
String.prototype.repeat = function(num){
return new Array(num + 1).join(this);
}
var filter = ['ass', 'piss'];
$('.post').text(function(i, txt){
// iterate over all words
for(var i=0; i<filter.length; i++){
// Create a regular expression and make it global
var pattern = new RegExp('\\b' + filter[i] + '\\b', 'g');
// Create a new string filled with '*'
var replacement = '*'.repeat(filter[i].length);
txt = txt.replace(pattern, replacement);
}
// returning txt will set the new text value for the current element
return txt;
});
Working example on jsFiddle
Edit: Added boundaries so it won't replace words that contain the swear words. I've used double backslashes because backslashes should be escaped in a string, see this topic.
You'll want to iterate over all the words: for each word, check if its one of your banned words before replacing it with asterisks.
In order to do this efficiently, you'll want to store the words in a hashtable:
var badWords = {
hello: true,
goodbye: true,
};
Iterate over each word and then see if it is in the hashtable. (The interpretation of what comprises a "word" varies, depending on if you are just looking for characters surrounded by whitespace or other non-alpha characters.)
// Pseudocode
for each word in content {
if (badWords[word]) {
// replace word with word.length * characters
}
}
Here is a lightweight function.
var filterWords = ["fool", "dumb", "shit", "ass", "couch potato"];
var rgx = new RegExp(filterWords.join("|"), "gi");
function wordFilter(str) {
return str.replace(rgx, "****");
}
When moving things from server to client, you must always consider bandwidth against processing cost. Sure, having it on the client-side will minimize you processing costs, but you will waste a lot of time moving the list of bad words to the client.
Besides, having it on server may enable you to pre-process posts, for example, and only update it when a rule change, saving even more process time.
So I've taken the base suggestion that @Harmen gave and I extended it into a jQuery plugin. This seems to be the best implementation that I could possibly come up with.
jQuery.profanityFilter
$(document).profanityFilter({
replaceWith:'#',
customSwears: ['ass'],
externalSwears: '/swearWords.json'
})
The JSON object you return cannot have repeated attribute names. Instead of { w: 'Swear1', w: 'Swear2' }
it should be [ 'Swear1', 'Swear2' ]
.
You can parse the text to filter and wrap every occurrence of a swear word between <span>
tags with a particular class attribute and toggle them with a function. That should be a simple approach.