2010-12-27 15 views
8

Sé que hay muchos argumentos sobre por qué esta es una mala idea, pero en mi implementación estoy planeando habilitar/deshabilitar palabras malas en la configuración de la cuenta. En otras palabras, las palabras malas serán visibles por defecto, pero apagadas/ocultas si se le pregunta.¿cómo puedo hacer una jQuery jurar palabra/mala palabra filtro?

El plan será enviar una cadena JSON al cliente y dejar que el cliente filtre las palabras incorrectas.

cadena JSON

['swear1', 'swear2'] 

frase original

this phrase includes swear1 

salida final

this phrase includes **** 

esto es lo que he probado hasta ahora

$(document).ready (function() { 
     $('body').html().replace('asdf', 'ffff'); 
    }); 

ahora en una nota al margen, estoy usando asp.net mvc y "podría" hacer esto por el lado del servidor, pero estaba pensando que esto sería mejor si se descargara al cliente ... Estoy abierto a sugerencias en este.

+1

El JSON-secuencia es incorrecta, 'W' no es única ... Debe ser una matriz de esta manera:' { "w": [ "jurar"', "swear2" ]} ' – Harmen

+3

Este código todavía tiene síndrome clbutético, ¿no? Eso puede ser indeseable incluso para un filtro de aceptación –

+0

No puede. Los filtros de "mala palabra" son una idea fundamentalmente errónea, e incluso las mejores implementaciones molestan a los usuarios al menos una docena de veces con falsos positivos por cada vez que realmente lo ayuda. Cualquier cosa que ocurra molesta a los usuarios cientos de veces. Ver también: clbuttic. Y ninguno puede evitar que incluso una persona estúpida y perezosa insulte a otra persona. Además, la validación del lado del cliente se puede eludir fácilmente. – delnan

Respuesta

2

Así que he tomado la sugerencia básica que @Harmen dio y la extendí a un plugin jQuery. Esta parece ser la mejor implementación que podría tener.

jQuery.profanityFilter

$(document).profanityFilter({ 
    replaceWith:'#', 
    customSwears: ['ass'], 
    externalSwears: '/swearWords.json' 
}) 
+0

Hola, ¿cómo puedo evitar malas palabras árabes? ¿es posible usar profanityFilter? – weblover

0

El objeto JSON que devuelve no puede tener nombres de atributos repetidos. En lugar de { w: 'Swear1', w: 'Swear2' } debe ser [ 'Swear1', 'Swear2' ].

Puede analizar el texto para filtrar y ajustar cada aparición de una maldición entre etiquetas <span> con un atributo de clase particular y alternarlas con una función. Ese debería ser un enfoque simple.

+0

lo siento, aún no había llegado al JSON, estoy más preocupado por la función de reemplazo real. –

+0

No mejoró el JSON ... – Harmen

+0

@Harmen: en realidad, sí. Usar el mismo nombre de atributo más de una vez simplemente devolverá el último valor asignado para ese atributo. – ncuesta

1

Al mover cosas de servidor a cliente, siempre debe considerar el ancho de banda contra el costo de procesamiento. Claro, tenerlo en el lado del cliente minimizará los costos de procesamiento, pero perderá mucho tiempo moviendo la lista de malas palabras al cliente.

Además, tenerlo en el servidor puede permitirle preprocesar las publicaciones, por ejemplo, y solo actualizarlo cuando cambie una regla, lo que ahorra aún más tiempo de proceso.

+0

+1 - Sí, realmente no había pensado en los costos de ancho de banda con JSON. Este es un argumento válido –

+1

Si se utiliza el almacenamiento en caché (y lo más probable es que lo sea), el ancho de banda solo se usará una vez. – brildum

+0

He agregado mi propia respuesta a esta vieja pregunta. Escribí un filtro de blasfemia jQuery, y en él paso el JSON al cliente una vez y, donde sea posible, lo almaceno en 'localStorage' –

12

Algo como esto podría funcionar:

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; 
}); 

Trabajando example en jsFiddle

Editar: límites Añadido por lo que no va a sustituir las palabras que contienen el palabrotas. He usado barras diagonales inversas dobles porque las barras diagonales inversas deben escaparse en una cadena, see this topic.

+0

, esto funciona muy bien. Tuve que hacer una modificación '$ ('body'). Html' en lugar de' $ ('. Post'). Text' porque usar '.text' hizo que el resultado fuera texto plano y no html. –

+0

¿cómo haré el filtro regex solo palabras completas? IE: ** culo ** necesita ser filtrado pero ** bajo ** no. Intenté agregar '^' y '$' en el "patrón", en el "txt.replace" y también en la cadena "filtro" JSON original. Pero fue en vano. Probablemente porque estaba buscando el comienzo del 'cuerpo' para comenzar con" jurar1 "en el que obviamente no es así. –

+0

Para eso necesitarás límites como este: '\ b ... \ b', actualizaré mi respuesta;) – Harmen

-1

Querrá iterar sobre todas las palabras: para cada palabra, verifique si es una de sus palabras prohibidas antes de reemplazarla con asteriscos.

Para hacer esto de manera eficiente, tendrá que almacenar las palabras en una tabla hash:

var badWords = { 
    hello: true, 
    goodbye: true, 
}; 

iterar sobre cada palabra y luego ver si está en la tabla hash. (La interpretación de lo que comprende una "palabra" varía, dependiendo de si solo está buscando caracteres rodeados de espacios en blanco u otros caracteres no alfa.)

// Pseudocode 
for each word in content { 
    if (badWords[word]) { 
     // replace word with word.length * characters 
    } 
} 
4

Aquí hay una función liviana.

var filterWords = ["fool", "dumb", "shit", "ass", "couch potato"]; 
var rgx = new RegExp(filterWords.join("|"), "gi"); 
function wordFilter(str) {   
    return str.replace(rgx, "****");    
} 
Cuestiones relacionadas