Por ejemplo, esta expresión regular
(.*)<FooBar>
coincidirá:
abcde<FooBar>
Pero, ¿cómo hago para que coincida en varias líneas?
abcde
fghij<FooBar>
Por ejemplo, esta expresión regular
(.*)<FooBar>
coincidirá:
abcde<FooBar>
Pero, ¿cómo hago para que coincida en varias líneas?
abcde
fghij<FooBar>
Respuestas:
Depende del idioma, pero debe haber un modificador que pueda agregar al patrón regex. En PHP es:
/(.*)<FooBar>/s
La s al final hace que el punto coincida con todos los caracteres, incluidas las nuevas líneas.
s
modificador. En cambio, hazlo [^]*
por el mismo efecto.
m
modificador
Prueba esto:
((.|\n)*)<FooBar>
Básicamente dice "cualquier carácter o una nueva línea" repetido cero o más veces.
((.|\n|\r)*)<FooBar>
[\s\S]*
o (?s).*
.
La pregunta es, ¿puede el .
patrón coincidir con algún personaje? La respuesta varía de un motor a otro. La principal diferencia es si el patrón lo utiliza una biblioteca de expresiones regulares POSIX o no POSIX.
Nota especial sobre patrones de lua: no se consideran expresiones regulares, pero .
coinciden con cualquier carácter allí, igual que los motores basados en POSIX.
Otra nota sobre matlab y octava: .
coincide con cualquier carácter por defecto ( demo ): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');
( tokens
contiene un abcde\n fghij
elemento).
Además, en todos aumentarLa expresión regular de las expresiones regulares es que el punto coincide con los saltos de línea de forma predeterminada. La gramática ECMAScript de Boost le permite desactivar esto con regex_constants::no_mod_m
( fuente ).
Como para oráculo(está basado en POSIX), use la n
opción ( demo ):select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual
Motores basados en POSIX :
Un simple .
salto de línea ya coincide, no es necesario utilizar ningún modificador, veagolpetazo( demo )
los tcl( demo ),postgresql( demo ),r(TRE, motor predeterminado base R sin perl=TRUE
, para la base R con perl=TRUE
o para los patrones stringr / stringi , use el (?s)
modificador en línea) ( demo ) también se trata de .
la misma manera.
Sin embargo , la mayoría de las herramientas basadas en POSIX procesan la entrada línea por línea. Por lo tanto, .
no coincide con los saltos de línea solo porque no están dentro del alcance. Aquí hay algunos ejemplos de cómo anular esto:
sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'
( H;1h;$!d;x;
extrae el archivo en la memoria). Si se deben incluir líneas completas, sed '/start_pattern/,/end_pattern/d' file
(la eliminación del inicio finalizará con las líneas coincidentes incluidas) o sed '/start_pattern/,/end_pattern/{{//!d;};}' file
(con las líneas coincidentes excluidas) puede considerarse.perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"
( -0
sorbe todo el archivo en la memoria, -p
imprime el archivo después de aplicar la secuencia de comandos dada por -e
). Tenga en cuenta que el uso -000pe
arrastrará el archivo y activará el 'modo de párrafo' donde Perl usa líneas nuevas consecutivas ( \n\n
) como separador de registros.grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file
. Aquí, z
habilita (?s)
la extracción de archivos, habilita el modo DOTALL para el .
patrón, (?i)
habilita el modo insensible a mayúsculas y minúsculas, \K
omite el texto coincidente hasta ahora, *?
es un cuantificador diferido, (?=<Foobar>)
coincide con la ubicación anterior <Foobar>
.pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file
( M
habilita la extracción de archivos aquí). Note pcregrep
es una buena solución para grep
usuarios de Mac OS .Motores no basados en POSIX :
s
modificador PCRE_DOTALL modificador : preg_match('~(.*)<Foobar>~s', $s, $m)
( demo )RegexOptions.Singleline
bandera ( demo ): var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
(?s)
opción en línea:$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
s
modificador (o (?s)
versión en línea al inicio) ( demo ):/(.*)<FooBar>/s
re.DOTALL
(o re.S
) banderas o (?s)
modificador en línea ( demostración ): m = re.search(r"(.*)<FooBar>", s, flags=re.S)
(y luego if m:
, print(m.group(1))
)Pattern.DOTALL
modificador (o (?s)
bandera en línea ) ( demo ):Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
(?s)
modificador en patrón ( demo ):regex = /(?s)(.*)<FooBar>/
(?s)
modificador ( demo ):"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
[^]
o soluciones alternativas [\d\D]
/ [\w\W]
/ [\s\S]
( demo ):s.match(/([\s\S]*)<FooBar>/)[1]
std::regex
) Use [\s\S]
o las soluciones alternativas de JS ( demo ):regex rex(R"(([\s\S]*)<FooBar>)");
vba vbscript- Utilizar el mismo enfoque que en JavaScript, ([\s\S]*)<Foobar>
. ( NOTA : La MultiLine
propiedad del
RegExp
objeto a veces se piensa erróneamente que la opción de permitir .
partido a través de los saltos de línea, mientras que, de hecho, sólo cambia el ^
y $
el comportamiento para que coincida con inicio / final de las líneas en lugar de cadenas , igual que en JS expresiones regulares ) comportamiento)
rubí- Utilice el modificador /m
MULTILINE ( demo ):s[/(.*)<Foobar>/m, 1]
(?s)
: regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]
( demo )stringr
/ stringi
regex que funcionan con el motor regex de ICU, también usan (?s)
: stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]
( demo )(?s)
en línea al inicio ( demo ):re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
dotMatchesLineSeparators
o (más fácil) pase el (?s)
modificador en línea al patrón:let rx = "(?s)(.*)<Foobar>"
(?s)
funciona de la manera más fácil, pero así es como se puede usar la opción :NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionDotMatchesLineSeparators error:®exError];
(?s)
modificador ( demo ): "(?s)(.*)<Foobar>"
(en hojas de cálculo de Google, =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>")
)NOTAS SOBRE(?s)
:
En la mayoría de los motores que no son POSIX, (?s)
el modificador en línea (o la opción de marca incrustada) se puede utilizar para hacer cumplir los .
saltos de línea.
Si se coloca al comienzo del patrón, (?s)
cambia el comportamiento de todos .
en el patrón. Si el (?s)
se coloca en algún lugar después del comienzo, solo .
se verán afectados aquellos que se encuentran a la derecha del mismo, a menos que este sea un patrón pasado a Python re
. En Python re
, independientemente de la (?s)
ubicación, .
se ve afectado todo el patrón . El (?s)
efecto se deja de usar (?-s)
. Un grupo modificado se puede usar para afectar solo un rango especificado de un patrón de expresiones regulares (por ejemplo, Delim1(?s:.*?)\nDelim2.*
hará que la primera .*?
coincidencia entre las nuevas líneas y la segunda .*
solo coincida con el resto de la línea).
Nota POSIX :
En motores regex que no son POSIX, para que coincida con cualquier carácter, se pueden usar [\s\S]
/ [\d\D]
/ [\w\W]
construcciones.
En POSIX, [\s\S]
no coincide con ningún carácter (como en JavaScript o cualquier motor que no sea POSIX) porque las secuencias de escape de expresiones regulares no son compatibles dentro de las expresiones de paréntesis. [\s\S]
se analiza como expresiones de paréntesis que coinciden con un único carácter, \
o s
o S
.
#define MOD regex_constants::perl | boost::regex::no_mod_s | boost::regex::no_mod_m
para sus banderas de expresiones regulares para reflejar eso. Y el árbitro siempre es el modificador en línea. Donde se (?-sm)(?s).*
restablece.
.
coincide con cualquier carácter allí (incluidos los saltos de línea). Vea esta demostración en línea de Bash .
Go
en la respuesta!
Si está utilizando la búsqueda de Eclipse, puede habilitar la opción "DOTALL" para hacer '.' coincide con cualquier carácter, incluidos los delimitadores de línea: simplemente agregue "(? s)" al comienzo de su cadena de búsqueda. Ejemplo:
(?s).*<FooBar>
(?s)
=>(?m)
En muchos dialectos de expresiones regulares, /[\S\s]*<Foobar>/
hará exactamente lo que quieras. Fuente
([\s\S]*)<FooBar>
El punto coincide con todos excepto las nuevas líneas (\ r \ n). Entonces use \ s \ S, que coincidirá con TODOS los caracteres.
[text rangeOfString:regEx options:NSRegularExpressionSearch]
. ¡Gracias!
<FooBar>
En rubí rubípuedes usar la m
opción ' ' (multilínea):
/YOUR_REGEXP/m
Consulte la documentación de Regexp en ruby-doc.org para obtener más información.
también podemos usar
(.*?\n)*?
para que coincida con todo, incluida la nueva línea sin codicia
Esto hará que la nueva línea sea opcional.
(.*?|\n)*?
"."
normalmente no coincide con saltos de línea. La mayoría de los motores regex le permiten agregar S
-flag (también llamado DOTALL
y SINGLELINE
) para hacer "."
coincidir también las nuevas líneas. Si eso falla, podrías hacer algo así [\S\s]
.
/(.*)<FooBar>/s
la s hace que el Punto (.) coincida con los retornos de carro
s
banderas existen en PCRE, el motor más completo (disponible en Perl y PHP). PCRE tiene 10 banderas (y muchas otras características) mientras que JavaScript solo tiene 3 banderas ( gmi
).
En la expresión regular basada en Java puedes usar [\s\S]
s
bandera al patrón en Java y JavaScript no tiene la s
bandera.
Tenga en cuenta que (.|\n)*
puede ser menos eficiente que (por ejemplo) [\s\S]*
(si las expresiones regulares de su idioma admiten tales escapes) y que encontrar la forma de especificar el modificador que hace. También coinciden con las nuevas líneas. O puedes ir con POSIXy alternativas como [[:space:][:^space:]]*
.
Use el modificador de patrón sU obtendrá la coincidencia deseada en PHP.
preg_match('/(.*)/sU',$content,$match);
http://dreamluverz.com/developers-tools/regex-match-all-incuding-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php
En el contexto de uso dentro de los idiomas, las expresiones regulares actúan sobre cadenas, no líneas. Por lo tanto, debería poder usar la expresión regular normalmente, suponiendo que la cadena de entrada tenga varias líneas.
En este caso, la expresión regular dada coincidirá con la cadena completa, ya que "<FooBar>" está presente. Dependiendo de los detalles de la implementación de expresiones regulares, el valor de $ 1 (obtenido de "(. *)") Será "fghij" o "abcde \ nfghij". Como otros han dicho, algunas implementaciones le permiten controlar si el "." coincidirá con la nueva línea, dándole la opción.
El uso de expresiones regulares basadas en líneas generalmente es para líneas de comando como egrep.
Tuve el mismo problema y lo resolví probablemente de la mejor manera, pero funciona. Reemplacé todos los saltos de línea antes de hacer mi partido real:
mystring= Regex.Replace(mystring, "\r\n", "")
Estoy manipulando HTML para que los saltos de línea realmente no me importen en este caso.
Intenté todas las sugerencias anteriores sin suerte, estoy usando .Net 3.5 FYI
(\s|\S)
parece hacer el truco para mí!
(?s)
para hacer .
coincidir cualquier carácter. No lo use, (\s|\S)
esto disminuirá el rendimiento.
En Javascript puede usar [^] * para buscar caracteres de cero a infinito, incluidos los saltos de línea.
$("#find_and_replace").click(function() {
var text = $("#textarea").val();
search_term = new RegExp("[^]*<Foobar>", "gi");;
replace_term = "Replacement term";
var new_text = text.replace(search_term, replace_term);
$("#textarea").val(new_text);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij<Foobar></textarea>
generalmente . no coincide con las nuevas líneas, así que intente((.|\n)*)<foobar>
\r
.:((?:.|\r?\n)*)<foobar>
Quería hacer coincidir un bloque if particular en Java
...
...
if(isTrue){
doAction();
}
...
...
}
Si uso el regExp
if \(isTrue(.|\n)*}
incluía la llave de cierre para el bloque de método, así que utilicé
if \(!isTrue([^}.]|\n)*}
para excluir la llave de cierre de la coincidencia con comodines.
A menudo tenemos que modificar una subcadena con algunas palabras clave repartidas entre las líneas que preceden a la subcadena. Considere un elemento xml:
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>81</PercentComplete>
</TASK>
Supongamos que queremos modificar el 81, a algún otro valor, digamos 40. Primero identifique .UID.21..UID.
, luego omita todos los caracteres incluyendo \n
hasta .PercentCompleted.
. El patrón de expresión regular y la especificación de reemplazo son:
String hw = new String("<TASK>\n <UID>21</UID>\n <Name>Architectural design</Name>\n <PercentComplete>81</PercentComplete>\n</TASK>");
String pattern = new String ("(<UID>21</UID>)((.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
String replaceSpec = new String ("$1$2$440$6");
//note that the group (<PercentComplete>) is $4 and the group ((.|\n)*?) is $2.
String iw = hw.replaceFirst(pattern, replaceSpec);
System.out.println(iw);
<TASK>
<UID>21</UID>
<Name>Architectural design</Name>
<PercentComplete>40</PercentComplete>
</TASK>
El subgrupo (.|\n)
es probablemente el grupo que falta $3
. Si lo hacemos sin captura para (?:.|\n)
entonces, el $3
es (<PercentComplete>)
. Entonces el patrón y replaceSpec
también puede ser:
pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")
y el reemplazo funciona correctamente como antes.
Normalmente, buscar tres líneas consecutivas en Powershell se vería así:
$file = get-content file.txt -raw
$pattern = 'lineone\r\nlinetwo\r\nlinethree\r\n' # "windows" text
$pattern = 'lineone\nlinetwo\nlinethree\n' # "unix" text
$pattern = 'lineone\r?\nlinetwo\r?\nlinethree\r?\n' # both
$file -match $pattern
# output
True
Curiosamente, este sería el texto de Unix en el mensaje, pero el texto de Windows en un archivo:
$pattern = 'lineone
linetwo
linethree
'
Aquí hay una manera de imprimir los finales de línea:
'lineone
linetwo
linethree
' -replace "`r",'\r' -replace "`n",'\n'
# output
lineone\nlinetwo\nlinethree\n
Una forma sería usar la s
bandera (al igual que la respuesta aceptada):
/(.*)<FooBar>/s
Una segunda forma sería usar la m
bandera (multilínea) y cualquiera de los siguientes patrones:
/([\s\S]*)<FooBar>/m
o
/([\d\D]*)<FooBar>/m
o
/([\w\W]*)<FooBar>/m
jex.im visualiza expresiones regulares: