Búsqueda de texto en JavaScript

Recientemente necesité crear en una aplicación web una búsqueda de texto en JavaScript que me permitiera señalar dicho texto directamente en la página modificando el DOM para ello.

Los scripts que abundan en la red, explican como buscar un texto dentro de una cadena pero muchos se centran en verificar si aparece o no usando para esto los métodos indexOf o search de la clase String:

Usando el método indexOf

var cadena = "Esto es una prueba";
var palabra = "prueba";

var index = cadena.indexOf(palabra);

if(index >= 0) {

	console.log("la palabra existe dentro de la cadena y se encuentra en la posición " + index);

}else{

	console.log("la palabra no existe dentro de la cadena");

}

Usando el método search

var cadena = "Esto es una prueba";
var expression = /prueba/;

var index = cadena.search(expression);

if(index >= 0) {

	console.log("la palabra existe dentro de la cadena y se encuentra en la posición " + index);

}else{

	console.log("la palabra no existe dentro de la cadena");

}

Pero lo que necesitaba era que la búsqueda se realizara directamente en el DOM y señalara todas las coincidencias, así que seguí buscando. Otro de los scripts que encontré se limitaba a hacer lo siguiente con jQuery:

Documento html


<div id="paragraph">
	<p>Esto es una prueba</p>
	<p>Pero una prueba sencilla</p>
</div>

Código JavaScript

var palabra = "prueba";

$("#paragraph p").each(function(){

    $(this).html( "<span>" + $(this).html().split(" ").join("</span> <span>") + "</span>" );

});

$("#paragraph span:contains('" + palabra + "')").css("color", "#F00");

Básicamente este método toma todas las palabras que se encuentren dentro de las etiquetas <p> y las rodea de una etiqueta <span>, después para buscar una palabra busca algún span que contenga la palabra y le añade una clase para señalarlo.

A pesar de lo sencillo del método tenía un problema y era que el contenido en el que deseaba buscar podía contener otras etiquetas html como <img> y esto añadiría spans alrededor de todos los parámetros de las imágenes. Por otro lado este script supone que deseo buscar sólo una palabra, si se necesita buscar una frase no funcionaría pues no existiría ningún span con más de una palabra dentro.

Entonces me dispuse a crear mi propio script usando expresiones regulares y esta pequeña función fue el resultado:

Función de búsqueda de texto en JavaScript

function searchInText (word, html) {

    //---Eliminar los spans
    html = html.replace(/<span class="finded">(.*?)<\/span>/g, "$1");

    //---Crear la expresión regular que buscará la palabra
    var reg = new RegExp(word.replace(/[\[\]\(\)\{\}\.\-\?\*\+]/, "\\$&"), "gi");
    var htmlreg = /<\/?(?:a|b|br|em|font|img|p|span|strong)[^>]*?\/?>/g;

    //---Añadir los spans
    var array;
    var htmlarray;
    var len = 0;
    var sum = 0;
    var pad = 28 + word.length;

    while ((array = reg.exec(html)) != null) {

        htmlarray = htmlreg.exec(html);

        //---Verificar si la búsqueda coincide con una etiqueta html
        if (htmlarray != null && htmlarray.index < array.index && htmlarray.index + htmlarray[0].length > array.index + word.length) {

            reg.lastIndex = htmlarray.index + htmlarray[0].length;

            continue;

        }

        len = array.index + word.length;

        html = html.slice(0, array.index) + "<span class='finded'>" + html.slice(array.index, len) + "</span>" + html.slice(len, html.length);

        reg.lastIndex += pad;

        if (htmlarray != null) htmlreg.lastIndex = reg.lastIndex;

        sum++;

    }

    return {total: sum, html: html};

}

Parámetros a enviar

word Palabra a buscar
html Código html dónde se buscará la palabra

Valor devuelto

La función devolverá un objeto con dos propiedades:

total Cantidad de veces que aparece la palabra en el código html
html Nuevo código html con spans con una clase específica (finded) alrededor de la palabra encontrada

Demostración de la función de búsqueda de texto en JavaScript

Ver la demostración

Descarga de ficheros

Descarga los ficheros de ejemplo

1 estrella2 estrellas3 estrellas4 estrellas5 estrellas (1 votos, promedio: 5,00 de 5)
Comparte este artículo:

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Puedes situar fragmentos de código dentro de etiquetas <pre></pre> y código HTML o XML entre etiquetas <xmp></xmp>.

Time limit is exhausted. Please reload CAPTCHA.