Regex para que coincida con la cadena que contiene dos nombres en cualquier orden

180

Necesito lógica Y en expresiones regulares.

algo como

Jack y James

de acuerdo con las siguientes cadenas

  • 'Hola Jack, aquí está James '

  • 'Hola James, aquí está Jack '

Meloun
fuente
1
Posible duplicado: mulitple-words-in-any-order-using-regex
Anderson Green
@AndersonGreen, la pregunta fue bloqueada prematuramente. Las respuestas son severamente deficientes ya que esas soluciones no son viables ya que la mayoría de las expresiones regulares no reconocen la búsqueda y el cuantificador de modo . Creo que el cuantificador existía en el punto de la pregunta que se hacía.
XPMai

Respuestas:

261

Puede hacer comprobaciones usando lookarounds :

^(?=.*\bjack\b)(?=.*\bjames\b).*$

Pruébalo.

Este enfoque tiene la ventaja de que puede especificar fácilmente múltiples condiciones.

^(?=.*\bjack\b)(?=.*\bjames\b)(?=.*\bjason\b)(?=.*\bjules\b).*$
Alin Purcaru
fuente
18
¿Le importaría a alguien explicar con un poco más de detalle cómo funciona este ejemplo?
bjmc
2
vimsintaxis: ^\(.*\<jack\>\)\@=\(.*\<james\>\@=\).*$o\v^(.*<jack>)@=(.*<james>)@=.*$
mykhal
¿Alguien sabe por qué esto se rompería (al menos en JavaScript) cuando trato de buscar cadenas que comiencen con '#'? ^(?=.*\b#friday\b)(?=.*\b#tgif\b).*$no coincide blah #tgif blah #friday blahpero ^(?=.*\bfriday\b)(?=.*\btgif\b).*$funciona bien.
btleffler
2
¿Qué \bsignifica aquí?
VarunAgw
1
@VarunAgw Límite de palabras . regular-expressions.info/refwordboundaries.html
Alin Purcaru
106

Tratar:

james.*jack

Si quieres ambos al mismo tiempo, entonces orellos:

james.*jack|jack.*james
icyrock.com
fuente
1
La respuesta aceptada funcionó. Esto también funcionó perfectamente para mí. Para buscar código en Visual Studio, 'buscar resultados'.
Yogurt The Wise
1
¡Esto funciona para mí y es mucho más conciso y fácil de entender que la respuesta aceptada!
Kumar Manish
1
Necesitaba una solución que solo tuviera dos nombres para coincidir, por lo que esta respuesta es más concisa para ese caso. Pero la respuesta aceptada se vuelve más concisa más allá de 2 ya que el número de "o" s aumenta factorialmente. Para 3 nombres habría 6 "o" s, 4 nombres serían 24 "o" s, etc.
WileCau
Yo recomendaría hacerlo perezoso james.*?jack|jack.*?james. Esto ayudará en textos grandes.
Jekis
42

Explicación del comando que voy a escribir : -

. significa cualquier carácter, el dígito puede reemplazarlo.

* significa cero o más ocurrencias de cosas escritas justo antes.

|significa 'o' .

Entonces,

james.*jack

buscaría james , luego cualquier número de caracteres hasta que jackllegue.

Ya que quieres jack.*jamesojames.*jack

De ahí el comando :

jack.*james|james.*jack
Shubham Sharma
fuente
77
Como nota al margen: también podría haber editado la respuesta de @ icyrock (que es la misma que la suya, solo 6 años antes), su explicación es muy útil por sí sola.
WoJ
2
Gracias por esta respuesta, sin embargo, siento la necesidad de señalar que en la búsqueda de VSCode, su conector de respuesta . * James | james. * jack tomará los espacios entre el '|' (o) símbolo en consideración durante la búsqueda. jack. * james | james. * jack funciona y no busca los espacios
jgritten
2
IF $ _explanation === "impresionante" ENTONCES devuelve $ THUMBS_UP ENDIF;
Syed Aqeel
9

Es corto y dulce

(?=.*jack)(?=.*james)
Shivam Agrawal
fuente
6

Tu puedes hacer:

\bjack\b.*\bjames\b|\bjames\b.*\bjack\b
codictorio
fuente
2

Vim tiene un operador de rama \&que es útil cuando se busca una línea que contenga un conjunto de palabras, en cualquier orden. Además, extender el conjunto de palabras requeridas es trivial.

Por ejemplo,

/.*jack\&.*james

coincidirá con una línea que contiene jacky james, en cualquier orden.

Consulte esta respuesta para obtener más información sobre el uso. No conozco ningún otro sabor regex que implemente la ramificación; el operador ni siquiera está documentado en la entrada de Wikipedia de Expresión regular .

Firstrock
fuente
2

MÉTODO 1: uno jacky unojames

En caso de que no se permitan dos jacko dos james, solo uno jacky uno jamesserían válidos, es probable que podamos diseñar una expresión similar a:

^(?!.*\bjack\b.*\bjack\b)(?!.*\bjames\b.*\bjames\b)(?=.*\bjames\b)(?=.*\bjack\b).*$

Aquí, excluiríamos esas instancias de pares usando estas declaraciones:

(?!.*\bjack\b.*\bjack\b)

y,

(?!.*\bjames\b.*\bjames\b)

Demo de RegEx 1

También podemos simplificar eso para,

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$

RegEx Demo 2


Si desea simplificar / modificar / explorar la expresión, se explica en el panel superior derecho de regex101.com . Si lo desea, también puede ver en este enlace cómo coincidiría con algunas entradas de muestra.


Circuito RegEx

jex.im visualiza expresiones regulares:

ingrese la descripción de la imagen aquí

Prueba

const regex = /^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b|.*\bjack\b).*$/gm;
const str = `hi jack here is james
hi james here is jack
hi james jack here is jack james
hi jack james here is james jack
hi jack jack here is jack james
hi james james here is james jack
hi jack jack jack here is james
`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}


MÉTODO 2: Uno jacky Uno jamesen orden específico

También se puede diseñar para el primero al jamesúltimo jack, similar al siguiente:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjames\b.*\bjack\b).*$

RegEx Demo 3

y viceversa:

^(?!.*\bjack\b.*\bjack\b|.*\bjames\b.*\bjames\b)(?=.*\bjack\b.*\bjames\b).*$

RegEx Demo 4

Emma
fuente
0

Puede utilizar la función de cuantificador de expresiones regulares, ya que es lookaroundposible que no sea compatible todo el tiempo.

(\b(james|jack)\b.*){2,}
XPMai
fuente