Quiero seleccionar texto específico entre dos cadenas usando expresiones regulares.
p.ej:
foo I have four toys bar //single line foo //multiline I have four toys bar foo I have three pets bar foo I have three pets barCómo seleccionar texto entre "foo" y "bar" con una palabra específica que contiene "cuatro"
Producción:
I have four toys I have four toysMi código:
foo[\s\S]*?(four)[\s\S]*?barMi código funciona bien, pero el problema es que cuando la palabra "cuatro" no se encuentra entre "foo" y "bar", está seleccionando todo el texto hasta la palabra "cuatro".
foo I have three pets bar foo I have four toys bar foo I have three pets barSolo quiero texto entre "foo" y "bar" cuando contiene la palabra específica "cuatro"
Podemos usar el siguiente patrón de expresiones regulares, en modo dot all:
\bfoo\s+(?:(?!\bbar\b).)*?\s+four\s+(?:(?!\bfoo\b).)*?\s+bar var input = `foo I have four toys bar foo I have four toys bar foo I have three pets bar foo I have three pets bar`; var matches = input.match(/\bfoo\s+(?:(?!\bbar\b).)*?\s+four\s+(?:(?!\bfoo\b).)*?\s+bar/gs) .map(x => x.replace(/^foo\s+|\s+bar$/g, "")); console.log(matches);Una explicación de este complejo patrón de expresiones regulares podría ser útil aquí:
\bfoo\s+ match 'foo' followed by one or more whitespace characters (?:(?!\bbar\b).)*? match any content WITHOUT encountering 'bar' \s+four\s+ match 'four' surrounded by whitespace (?:(?!\bfoo\b).)*? match any content WITHOUT encountering 'foo' \s+bar whitespace followed by ending 'bar' Tenga en cuenta que debido a la forma en que se comporta match() , también tenemos un paso de map en el que eliminamos foo inicial y la bar final de cada coincidencia.