solo - Expresión regular para obtener una cadena entre dos cadenas en Javascript
match javascript ejemplo (7)
He encontrado publicaciones muy similares pero no puedo obtener mi expresión regular aquí mismo.
Estoy intentando escribir una expresión regular que devuelve una cadena que se encuentra entre otras dos cadenas. Por ejemplo: quiero obtener la cadena que se encuentra entre las cadenas "vaca" y "leche"
Mi vaca siempre da leche
volvería
"siempre da"
Aquí está la expresión que he reconstruido hasta ahora:
(?=cow).*(?=milk)
Sin embargo, esto devuelve la cadena "vaca siempre da"
Expresión regular para obtener una cadena entre dos cadenas en Javascript
La solución más completa que funcionará en la gran mayoría de los casos es utilizar un grupo de captura con un patrón de coincidencia de puntos perezosos . Sin embargo, un punto .
en JS regex no coincide con los caracteres de salto de línea, por lo tanto, lo que funcionará en un 100% de casos es construcciones [^]
o [/s/S]
/ [/d/D]
/ [/w/W]
.
Escenario 1: entrada de línea única
cow (.*?) milk
primero se encuentra la cow
, luego un espacio, luego cualquier 0+ caracteres distintos de los caracteres line break, tan pocos como sea posible *?
es un cuantificador perezoso, se capturan en el Grupo 1 y luego debe seguir un espacio con milk
(y también se combinan y se consumen ).
Escenario 2: entrada de líneas múltiples
cow ([/s/S]*?) milk
Aquí, la cow
y un espacio se emparejan primero, luego cualquier 0+ caracteres lo menos posible se emparejan y se capturan en el Grupo 1, y luego se combina un espacio con milk
.
Escenario 3: coincidencias superpuestas
Si tiene una cadena como >>>15 text>>>67 text2>>>
y necesita obtener 2 coincidencias entre >>>
+ number
+ whitespace
y >>>
, no puede usar />>>/d+/s(.*?)>>>/g
ya que esto solo encontrará 1 coincidencia debido al hecho de que >>>
antes de que 67
ya se haya consumido al encontrar la primera coincidencia. Puede utilizar una búsqueda anticipada positiva para verificar la presencia del texto sin "engullirlo" realmente (es decir, agregarlo a la coincidencia):
/>>>/d+/s(.*?)(?=>>>)/g
Vea la demostración en línea de text2
que text2
y text2
como contenido del Grupo 1 encontrado.
Consulte también Cómo obtener todas las coincidencias posibles superpuestas para una cadena .
Consideraciones de rendimiento
El patrón de coincidencia de punto difuso ( .*?
) Dentro de los patrones de expresiones regulares puede ralentizar la ejecución del script si se proporciona una entrada muy larga. En muchos casos, la técnica de desenrollar el lazo ayuda en mayor medida. Tratando de tomar todo entre la cow
y la milk
de "Their/ncow/ngives/nmore/nmilk"
, vemos que solo tenemos que "Their/ncow/ngives/nmore/nmilk"
todas las líneas que no comienzan con milk
, por lo tanto, en lugar de cow/n([/s/S]*?)/nmilk
podemos usar:
/cow/n(.*(?:/n(?!milk$).*)*)/nmilk/gm
Vea la demostración de expresiones regulares (si puede haber /r/n
, use /cow/r?/n(.*(?:/r?/n(?!milk$).*)*)/r?/nmilk/gm
). Con esta pequeña cadena de prueba, la ganancia de rendimiento es insignificante, pero con texto muy grande, notará la diferencia (especialmente si las líneas son largas y los saltos de línea no son muy numerosos).
Ejemplo de uso de expresiones regulares en JavaScript:
//Single/First match expected: use no global modifier and access match[1] console.log("My cow always gives milk".match(/cow (.*?) milk/)[1]); // Multiple matches: get multiple matches with a global modifier and // trim the results if length of leading/trailing delimiters is known var s = "My cow always gives milk, thier cow also gives milk"; console.log(s.match(/cow (.*?) milk/g).map(function(x) {return x.substr(4,x.length-9);})); //or use RegExp#exec inside a loop to collect all the Group 1 contents var result = [], m, rx = /cow (.*?) milk/g; while ((m=rx.exec(s)) !== null) { result.push(m[1]); } console.log(result);
¿Qué tal si usamos la siguiente expresión regular?
(?<=My cow/s).*?(?=/smilk)
Aquí hay una expresión regular que captará lo que hay entre la vaca y la leche (sin espacio inicial / final):
srctext = "My cow always gives milk.";
var re = /(.*cow/s+)(.*)(/s+milk.*)/;
var newtext = srctext.replace(re, "$2");
Un ejemplo: http://jsfiddle.net/entropo/tkP74/
Pude obtener lo que necesitaba usando la solución de Martinho Fernandes a continuación. El código es:
var test = "Mi vaca siempre da leche";
var testRE = test.match ("vaca (. *) leche"); alerta (testRE [1]);
Notarás que estoy alertando a la variable testRE como una matriz. Esto es porque testRE está regresando como una matriz, por alguna razón. La salida de:
My cow always gives milk
Cambios en:
always gives
Una búsqueda anticipada (esa (?=
Parte) no consume ninguna entrada. Es una aserción de ancho cero (como lo son las comprobaciones de límites y las referencias).
Desea una coincidencia regular aquí, para consumir la porción de cow
. Para capturar la porción intermedia, utiliza un grupo de captura (simplemente coloque la porción del patrón que desea capturar entre paréntesis):
cow(.*)milk
Sin lookaheads son necesarios en absoluto.
- Necesitas capturar el
.*
- Puede (pero no tiene que) hacer el
.*
No.*
coreado Realmente no hay necesidad de mirar hacia adelante.
> /cow(.*?)milk/i.exec(''My cow always gives milk''); ["cow always gives milk", " always gives "]