Regex para hacer coincidir una cadena que contiene dos nombres en cualquier orden
Necesito Y lógico en expresiones regulares.
algo como
jack y james
de acuerdo con las siguientes cadenas
'Hola Jack, aquí está James '.
'Hola James, aquí está Jack '.
Puede realizar comprobaciones utilizando anticipaciones positivas . Aquí hay un resumen del indispensable regular-expressions.info :
La búsqueda hacia adelante y hacia atrás, denominadas colectivamente "búsqueda", son afirmaciones de longitud cero... la búsqueda en realidad coincide con caracteres, pero luego abandona la coincidencia y devuelve solo el resultado: coincidencia o no coincidencia. Por eso se les llama “afirmaciones”. No consumen caracteres en la cadena, solo afirman si una coincidencia es posible o no.
Luego continúa explicando que las búsquedas positivas se utilizan para afirmar que lo que sigue coincide con una determinada expresión sin ocupar caracteres en esa expresión coincidente.
Así que aquí hay una expresión que utiliza dos búsquedas positivas posteriores para afirmar que la frase coincide jack
y james
en cualquier orden:
^(?=.*\bjack\b)(?=.*\bjames\b).*$
Pruébalo.
Las expresiones entre paréntesis que comienzan con ?=
son las anticipaciones positivas. Voy a desglosar el patrón:
^
afirma el inicio de la expresión que va a coincidir.(?=.*\bjack\b)
es la primera mirada positiva que dice que lo que sigue debe coincidir.*\bjack\b
..*
significa cualquier carácter cero o más veces.\b
significa cualquier límite de palabra (espacio en blanco, inicio de expresión, final de expresión, etc.).jack
son literalmente esos cuatro caracteres seguidos (lo mismo parajames
la siguiente búsqueda positiva).$
afirma el final de la expresión que me coincide.
Entonces, la primera mirada hacia adelante dice "lo que sigue (y no es en sí mismo una mirada hacia adelante o hacia atrás) debe ser una expresión que comience con cero o más caracteres seguidos por un límite de palabra y luego jack
otro límite de palabra", y la segunda mirada hacia adelante dice "Lo que sigue debe ser una expresión que comience con cero o más caracteres seguidos de un límite de palabra y luego james
de otro límite de palabra". Después de las dos búsquedas anticipadas está .*
cuál simplemente coincide con cualquier carácter cero o más veces y $
cuál coincide con el final de la expresión.
"comience con cualquier cosa, luego jack o james y luego termine con cualquier cosa" satisface la primera búsqueda anticipada porque hay una cantidad de caracteres luego la palabra jack
, y satisface la segunda búsqueda anticipada porque hay una cantidad de caracteres (que casualmente incluyen jack
, pero que no es necesario para satisfacer la segunda búsqueda anticipada) luego la palabra james
. Ninguna búsqueda anticipada afirma el final de la expresión, por lo que lo .*
que sigue puede ir más allá de lo que satisface las búsquedas anticipadas, como "luego termina con cualquier cosa".
Creo que entiendes la idea, pero para que quede absolutamente claro, aquí está con jack
y james
al revés, es decir, "empieza con cualquier cosa, luego james o jack y luego termina con cualquier cosa"; satisface la primera búsqueda anticipada porque hay una cantidad de caracteres y luego la palabra james
, y satisface la segunda búsqueda anticipada porque hay una cantidad de caracteres (que casualmente incluyen james
, pero eso no es necesario para satisfacer la segunda búsqueda anticipada), luego el palabra jack
. Como antes, ninguna búsqueda anticipada afirma el final de la expresión, por lo que lo .*
que sigue puede ir más allá de lo que satisface las búsquedas anticipadas, como "luego termina con cualquier cosa".
Este enfoque tiene la ventaja de que puede especificar fácilmente múltiples condiciones.
^(?=.*\bjack\b)(?=.*\bjames\b)(?=.*\bjason\b)(?=.*\bjules\b).*$
Intentar:
james.*jack
Si quieres ambos al mismo tiempo, entonces or
:
james.*jack|jack.*james