javascript: haga coincidir la cadena con la matriz de expresiones regulares

6 minutos de lectura

avatar de usuario
usuario398341

¿Hay alguna forma en JavaScript de obtener un valor booleano para una coincidencia de la cadena con la matriz de expresiones regulares?

El ejemplo sería (donde la declaración ‘si’ representa lo que estoy tratando de lograr):

var thisExpressions = [ '/something/', '/something_else/', '/and_something_else/'];
var thisString = 'else';

if (matchInArray(thisString, thisExpressions)) {

} 

  • ¿Está buscando una coincidencia con todas las expresiones (AND) o cualquiera de las expresiones (OR)?

    – Arte

    14 de abril de 2012 a las 9:53

  • Con jquery puedes usar jQuery.inArray();

    – GillesC

    14 de abril de 2012 a las 9:56

avatar de usuario
andersh

Usando un enfoque más funcional, puede implementar la coincidencia con una sola línea usando un función de matriz:

ECMAScript 6:

const regexList = [/apple/, /pear/];
const text = "banana pear";
const isMatch = regexList.some(rx => rx.test(text));

ECMAScript 5:

var regexList = [/apple/, /pear/];
var text = "banana pear";
var isMatch = regexList.some(function(rx) { return rx.test(text); });

  • También vale la pena mencionar el filter método para Arrays, que a menudo es útil y se usa de la misma manera.

    – Sanjay Manohar

    18 de agosto de 2017 a las 1:54

  • Además, echa un vistazo .every si quieres que coincida con todo en la matriz vs .some que devuelve verdadero si coincide con alguno en la matriz.

    –Michael Warner

    4 de diciembre de 2019 a las 15:36

  • Esta debería ser la respuesta aceptada para JavaScript moderno.

    – DrCord

    19 de julio de 2021 a las 16:24

avatar de usuario
gillesc

http://jsfiddle.net/9nyhh/1/

var thisExpressions = [/something/, /something_else/, /and_something_else/];
var thisExpressions2 = [/else/, /something_else/, /and_something_else/];
var thisString = 'else';

function matchInArray(string, expressions) {

    var len = expressions.length,
        i = 0;

    for (; i < len; i++) {
        if (string.match(expressions[i])) {
            return true;
        }
    }

    return false;

};

setTimeout(function() {
    console.log(matchInArray(thisString, thisExpressions));
    console.log(matchInArray(thisString, thisExpressions2));
}, 200)​

  • ¿Por qué no eliminar la variable res por completo, devolver verdadero en su declaración if y devolver falso al final? Luego se detendrá al encontrar la primera coincidencia.

    – Arte

    14 de abril de 2012 a las 10:07

  • También usaría expresiones[i].test(cadena) en lugar de cadena.match()

    – Arte

    14 de abril de 2012 a las 10:08

  • Aunque este código puede responder a la pregunta, proporcionando contexto adicional con respecto a por qué y/o cómo responde a la pregunta mejoraría significativamente su valor a largo plazo. Edite su respuesta para agregar alguna explicación.

    –Toby Speight

    6 mayo 2016 a las 11:49

  • ¿Qué hay de decir que quería el índice del valor que coincidía?

    – Si8

    23/10/2018 a las 17:50

podrías usar .prueba() que devuelve un valor booleano cuando encuentra lo que busca en otra cadena:

var thisExpressions = [ '/something/', '/something_else/', '/and_something_else/'];
var thisString = new RegExp('\\b' + 'else' + '\\b', 'i');
var FoundIt = thisString.test(thisExpressions);  
if (FoundIt) { /* DO STUFF */ }

  • RegExp.prototype.test() no se puede usar con una matriz. Se necesita una cuerda. desarrollador.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

    – gdibble

    14/10/2015 a las 16:57


  • @gdibble funcionará, porque test llama toString en el argumento proporcionado, que, para matriz, será join(). ¡Probablemente no sea recomendable!

    – WickyNilliams

    23 oct 2015 a las 10:42

  • Ejemplo: /monkey/.test({ toString : () => "monkey" }) // true

    – WickyNilliams

    23 oct 2015 a las 10:42


  • @Likwid_T: ¿qué significa ‘\\b’? Sé que ‘i’ significa que no distingue entre mayúsculas y minúsculas, pero no pude encontrar en línea lo que significa \\b. Además, ¿por qué lo tienes dos veces?

    – GK79

    15 de noviembre de 2015 a las 15:17


  • @GK79 una \b es un límite de palabra, de modo que podría coincidir /\broller\b/ en solo la palabra ‘roller’ pero no coincidiría con ‘rollercoaster’, sin embargo, si quitara el final \b entonces coincidiría con la primera parte de ‘rollercoaster’

    – gdibble

    18 de noviembre de 2015 a las 1:17

mirar de esta manera…

function matchInArray(stringSearch, arrayExpressions){
    var position = String(arrayExpressions).search(stringSearch);
    var result = (position > -1) ? true : false
    return result;
}

Puede unir todas las expresiones regulares en una sola. De esta manera, la cadena se escanea solo una vez. Incluso con una expresión regular un poco más compleja.

var thisExpressions = [ /something/, /something_else/, /and_something_else/];
var thisString = 'else';


function matchInArray(str, expr) {
    var fullExpr = new RegExp(expr
        .map(x=>x.source) // Just if you need to provide RegExp instances instead of strings or ...
        // .map(x=>x.substring(1, x.length -2)  // ...if you need to provide strings enclosed by "https://stackoverflow.com/" like in original question.
        .join("|")
    )
    return str.match(fullExpr);

};


if (matchInArray(thisString, thisExpressions)) {
    console.log ("Match!!");
} 

De hecho, incluso con este enfoque, si necesita verificar el mismo conjunto de expresiones en varias cadenas, esto es un poco subóptimo porque está creando (y compilando) la misma expresión regular cada vez que se llama a la función.

Un mejor enfoque sería usar un generador de funciones como este:

var thisExpressions = [ /something/, /something_else/, /and_something_else/];
var thisString = 'else';

function matchInArray_builder(expr) {
    var fullExpr = new RegExp(expr
        .map(x=>x.source) // Just if you need to provide RegExp instances instead of strings or ...
        // .map(x=>x.substring(1, x.length -2)  // ...if you need to provide strings enclosed by "https://stackoverflow.com/" like in original question.
        .join("|")
    )   

    return function (str) {
        return str.match(fullExpr);

    };
};  

var matchInArray = matchInArray_builder(thisExpressions);

if (matchInArray(thisString)) {
    console.log ("Match!!");
} 

  • ¿Qué hay de decir que quería el índice del valor que coincidía?

    – Si8

    23/10/2018 a las 17:50

  • matchInArray(thisString, thisExpressions).index

    – bitifet

    23 oct 2018 a las 18:47

  • ¿Sería ir tras el var matchInArray = matchInArray_builder(thisExpressions);? como esto: var matchInArray = matchInArray_builder(thisExpressions); var index = matchInArray(thisString, thisExpressions).index?

    – Si8

    23 oct 2018 a las 19:02

  • No. Puse un parámetro extra por error. matchInArray() función devuelve el resultado de String.match(). Por lo tanto, de hecho, la condición “si” no es un valor booleano sino una estructura completa (que se evalúa como verdadera) informando la subcadena coincidente y su posición…

    – bitifet

    23 oct 2018 a las 19:16

  • ahhhhh … leí mal su declaración de devolución dentro de la función 🙂

    – Si8

    23 oct 2018 a las 19:22

avatar de usuario
usuario1429980

Considere dividir este problema en dos partes:

  1. filter sacar los elementos que match la expresión regular dada
  2. determinar si esa lista filtrada tiene 0 partidos en él
const sampleStringData = ["frog", "pig", "tiger"];

const matches = sampleStringData.filter((animal) => /any.regex.here/.test(animal));

if (matches.length === 0) {
  console.log("No matches");
}

  • ¿Qué hay de decir que quería el índice del valor que coincidía?

    – Si8

    23/10/2018 a las 17:50

  • matchInArray(thisString, thisExpressions).index

    – bitifet

    23 oct 2018 a las 18:47

  • ¿Sería ir tras el var matchInArray = matchInArray_builder(thisExpressions);? como esto: var matchInArray = matchInArray_builder(thisExpressions); var index = matchInArray(thisString, thisExpressions).index?

    – Si8

    23 oct 2018 a las 19:02

  • No. Puse un parámetro extra por error. matchInArray() función devuelve el resultado de String.match(). Por lo tanto, de hecho, la condición “si” no es un valor booleano sino una estructura completa (que se evalúa como verdadera) informando la subcadena coincidente y su posición…

    – bitifet

    23 oct 2018 a las 19:16

  • ahhhhh … leí mal su declaración de devolución dentro de la función 🙂

    – Si8

    23 oct 2018 a las 19:22

let expressions = [ '/something/', '/something_else/', '/and_something_else/'];

let str="else";

aquí estará el cheque para las siguientes expresiones:

if( expressions.find(expression => expression.includes(str) ) ) {

}

usando el método Array .find() para atravesar la matriz e .include para verificar la subcadena

¿Ha sido útil esta solución?