No distingue mayúsculas de minúsculas de la cadena de reemplazo en JavaScript?

Tengo que resaltar, caso de modo insensible, dado palabras clave en una cadena de JavaScript.

Por ejemplo:

  • highlight("foobar Foo bar FOO", "foo") debe devolver "<b>foo</b>bar <b>Foo</b> bar <b>FOO</b>"

Necesito el código de trabajo para cualquier palabra clave, y por lo tanto el uso de un duro expresión regular como /foo/i no es una solución suficiente.

¿Cuál es la manera más fácil de hacer esto?

(Esta un ejemplo de un problema más general detallada en el título, pero creo que es la mejor manera de abordar con una concreta, útil ejemplo).

InformationsquelleAutor | 2008-11-11

7 Kommentare

  1. 70

    Que puede el uso de expresiones regulares si usted prepara la cadena de búsqueda. En PHP por ejemplo, no es una función preg_quote, que reemplaza a todas las expresiones de caracteres en una cadena con sus escapó versiones.

    Aquí es una función de javascript:

    function preg_quote( str ) {
        //http://kevin.vanzonneveld.net
        //+   original by: booeyOH
        //+   improved by: Ates Goral (http://magnetiq.com)
        //+   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        //+   bugfixed by: Onno Marsman
        //*     example 1: preg_quote("$40");
        //*     returns 1: '\$40'
        //*     example 2: preg_quote("*RRRING* Hello?");
        //*     returns 2: '\*RRRING\* Hello\?'
        //*     example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
        //*     returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'
    
        return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
    }

    (Tomado de http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_preg_quote/ )

    Así se podrían hacer las siguientes:

    function highlight( data, search )
    {
        return data.replace( new RegExp( "(" + preg_quote( search ) + ")" , 'gi' ), "<b>$1</b>" );
    }
    • Puedo ver, sólo la primera ocurrencia es reemplazado. No sabía que reemplazar se comporta como esta. El preg_quote es importante si se quiere resaltar cadenas con / o * u otros caracteres regex.
    • Um.. que está javascript. Me acaba de decir que hay una función en PHP llamado preg_quote. A continuación he incluido un js versión de esa función, y una función js… estos ejemplos de código son js
    • Hay dos errores en el segundo fragmento de código: 1 – se necesita 'gi' en lugar de 'i' RegExp modificador, 2 – es la sustitución con search en vez de resaltar las subcadenas en data. El primer segmento de código puede o puede no ser una buena escaper de javascript (no sé) pero la llamaban preg_quote es engañosa, JS RegExp ≠ PCRE.
    • Esto funciona muy bien, sin embargo no devolver la correcta capitalizado (o no) la versión de que el término de búsqueda. si la búsqueda para «probar» en el texto «Hola Mundo de la Prueba», va a volver «Hola <b>prueba</b> Mundo» en lugar de «Hola <b>Prueba</b> Mundo». He arreglado cambiando el punto culminante de la función; a este return data.replace( new RegExp( "(" + preg_quote( search ) + ")" , 'gi' ), "<b>$1</b>" );
    • Usted no debería usar una expresión regular para esto en absoluto. Usted puede pasar el 'gi' banderas como un tercer argumento a replace. Usted no tiene que usar preg_quote o crear un RegExp ni nada por el estilo.
    • Hay, de hecho, un «banderas» método en Cadena.reemplazar, pero no es estándar, por lo tanto poco fiables. El mejor enfoque sería hacer un «relleno», método que selecciona una opción adecuada.
    • Como una cadena de extensión: String.el prototipo.toRegexFriendlyString = function () { return (a esto.toString() + «).reemplazar(/([\\\.\+*\?[\^]\$()\{\}\=\!\<\>\|\:])/g, «\\$1»); }; los datos de retorno.reemplazar(new RegExp(«(» + de búsqueda.toRegexFriendlyString() + «)», ‘gi’), «<span class=’highlight’>$1</span>»);
    • Las banderas se pasan a la regex aquí, no a la Cadena.función de reemplazar entonces está bien 🙂

  2. 64
    function highlightWords( line, word )
    {
         var regex = new RegExp( '(' + word + ')', 'gi' );
         return line.replace( regex, "<b>$1</b>" );
    }
    • Por supuesto, usted necesita tener cuidado con lo que va a sustituir y lo que usted está buscando en como @bobince notas. La anterior funcionará bien para el texto y la mayoría de las búsquedas si usted tiene cuidado de citar sus caracteres regex…
    • Este se ejecutará en problemas si hay caracteres regex en la palabra que está siendo reemplazado. @okoman la solución que se presenta en torno a eso.
    • Esto no funciona si el trabajo está a punto, cómo hacer que funcione en el caso de punto o varios puntos (ej: «…» )
    • esos son los caracteres especiales en una expresión regular. Usted necesita citar el uso de una barra diagonal inversa en primer lugar. Tenga en cuenta que la barra diagonal inversa es también una cita de carácter en una cadena por lo que necesita utilizar en dos en la cadena de reemplazo. word.replace(/\./g, '\\.')
  3. 13

    Puede mejorar el objeto RegExp con una función que hace especial carácter de escape para usted:

    RegExp.escape = function(str) 
    {
      var specials = /[.*+?|()\[\]{}\\$^]/g; //.*+?|()[]{}\$^
      return str.replace(specials, "\\$&");
    }

    A continuación, usted sería capaz de utilizar lo que los otros sugirieron sin ningún tipo de preocupaciones:

    function highlightWordsNoCase(line, word)
    {
      var regex = new RegExp("(" + RegExp.escape(word) + ")", "gi");
      return line.replace(regex, "<b>$1</b>");
    }
    • ? en javascript RegExp necesitan ser escapado con doble barra invertida como \\?
    • ¿Qué piensa usted de mi RegExp.escape función?
    • stackoverflow.com/questions/889957/… me he encontrado con problemas en los que el signo de interrogación necesarios para ser escapado con doble \ pero supongo que en [] usted no necesita para escapar de él.
    • De hecho, usted necesita para escapar de la pregunta marque sólo una vez para la expresión regular, por lo que terminará con \? cuando se utiliza una expresión literal. Pero usted necesita para escapar de la barra diagonal inversa mismo para JS cadenas, por lo que terminan con \\? al generar la expresión de una cadena. Y sí, en una clase de personaje es el único personaje que realmente debe de escape es ].
  4. 5

    Expresiones regulares están bien siempre y cuando las palabras clave son realmente palabras, sólo se puede utilizar una expresión regular constructor, en lugar de un literal para crear uno de una variable:

    var re= new RegExp('('+word+')', 'gi');
    return s.replace(re, '<b>$1</b>');

    La dificultad surge si ‘palabras clave’ puede tener signos de puntuación, como la puntuación tiende a tener un significado especial en regex. Por desgracia, a diferencia de la mayoría de los otros idiomas/bibliotecas con regexp apoyo, no hay ninguna función estándar para escapar de punctation para regex en JavaScript.

    Y no se puede estar totalmente seguro de lo personajes necesidad de escapar porque no todos los navegadores a la aplicación de regexp está garantizado a ser exactamente el mismo. (En particular, los nuevos navegadores pueden añadir nuevas funcionalidades.) Y de barra diagonal inversa escapar caracteres que no son especiales, no se garantiza que todavía funcionan, aunque en la práctica se hace.

    Así que lo mejor que puedes hacer es uno de:

    • tratando de atrapar a cada uno de los caracteres especiales en común navegador uso el día de hoy [añadir: ver a Sebastián receta]
    • barra diagonal inversa de escape de todos los no-caracteres alfanuméricos. atención: \W coincidirá también con la no-ASCII de los caracteres Unicode, que realmente no desea.
    • sólo asegúrese de que no hay caracteres alfanuméricos en la palabra clave antes de buscar

    Si usted está usando esto para resaltar las palabras en el lenguaje HTML que ya ha marcado, sin embargo, tienes problemas. Su ‘palabra’ podría aparecer en el nombre de un elemento o atributo de valor, en cuyo caso el intento de envolver a < b> alrededor de ella hará que el quebrantamiento. En escenarios más complicados, posiblemente, incluso un HTML-inyección XSS agujero de seguridad. Si usted tiene que lidiar con marcado necesitará más complicado enfoque, dividir ‘< … >’ marcado antes de intentar el proceso de cada tramo de texto en su propio.

  5. 5

    ¿Qué pasa con algo como esto:

    if(typeof String.prototype.highlight !== 'function') {
      String.prototype.highlight = function(match, spanClass) {
        var pattern = new RegExp( match, "gi" );
        replacement = "<span class='" + spanClass + "'>$&</span>";
    
        return this.replace(pattern, replacement);
      }
    }

    Esto podría ser llamado así:

    var result = "The Quick Brown Fox Jumped Over The Lazy Brown Dog".highlight("brown","text-highlight");
  6. 2

    Para los pobres con disregexia o regexophobia:

    JS:

    function replacei(str, sub, f){
    	let A = str.toLowerCase().split(sub.toLowerCase());
    	let B = [];
    	let x = 0;
    	for (let i = 0; i < A.length; i++) {
    		let n = A[i].length;
    		B.push(str.substr(x, n));
    		if (i < A.length-1)
    			B.push(f(str.substr(x + n, sub.length)));
    		x += n + sub.length;
    	}
    	return B.join('');
    }
    
    s = 'Foo and FOO (and foo) are all -- Foo.'
    t = replacei(s, 'Foo', sub=>'<'+sub+'>')
    console.log(t)

    De salida:

    <Foo> and <FOO> (and <foo>) are all -- <Foo>.
  7. 0

    ¿Por qué no acaba de crear una nueva expresión regular que en cada llamada a la función? Usted puede utilizar:

    new Regex([pat], [flags])

    donde [pat] es una cadena para el patrón, y [banderas] son las banderas.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea