Expresión regular para detenerse en la primera coincidencia
Frecuentes
Visto 704,686 veces
617
Mi patrón de expresiones regulares se parece a
<xxxx location="file path/level1/level2" xxxx some="xxx">
Solo me interesa la parte de las cotizaciones asignada a la ubicación. ¿No debería ser tan fácil como a continuación sin el codicioso interruptor?
/.*location="(.*)".*/
No parece funcionar.
9 Respuestas
1245
Debe hacer que su expresión regular no sea codiciosa, porque de forma predeterminada, "(.*)"
coincidirá con todos "file path/level1/level2" xxx some="xxx"
.
En su lugar, puede hacer que su punto estrella no sea codicioso, lo que hará que coincida con la menor cantidad de caracteres posible:
/location="(.*?)"/
Añadiendo un ?
en un cuantificador?
, *
or +
) lo hace no codicioso.
respondido 23 mar '10, 20:03
FWIW, en caso de que esté usando VIM, esta expresión regular debe ser un poco diferente: en lugar de .*?
es .\{-}
para un partido no codicioso. - SooDesuNe
Gracias Daniel "Agregar un? En un cuantificador (?, * O +) lo hace no codicioso". es un consejo útil para mí. - PhatHV
La ? describe mi confusión al tratar de resolver esto. Qué apropiado. - robbie smith
Creo que puedes decir 'vago' en lugar de 'no codicioso' - Manticore
Debido a que la pregunta no especifica un dialecto de expresiones regulares en particular, esta respuesta debe especificar que solo está disponible en motores de expresiones regulares que implementan las extensiones de Perl 5 (Java, Ruby, Python, etc.) pero no en motores de expresiones regulares "tradicionales" (incluido JavaScript , Awk, sed
, grep
sin -P
, etc.). - triples
59
location="(.*)"
coincidirá con el "después location=
hasta el "después some="xxx
a menos que lo hagas no codicioso. Entonces o necesitas .*?
(es decir, que no sea codicioso) o mejor reemplácelo .*
con [^"]*
.
respondido 23 mar '10, 20:03
[^ "] * también es probablemente más rápido con la mayoría de los motores de expresiones regulares porque no necesita buscar el patrón después del patrón actual. Juan Vicente
@Kip: Probablemente tengas razón, pero el .*?
la notación es más general que [^"]*
- Bondax
¿qué tal si quiero incluir el carácter delimitador usando [^ "] * - Fróhlich
en absoluto, si no sabe lo que ^ y [] significan aquí. La mayoría de la gente lo entenderá. * - vicente gerris
34
¿Qué tal
.*location="([^"]*)".*
Esto evita la búsqueda ilimitada con. * Y coincidirá exactamente con la primera cotización.
Respondido 21 Feb 13, 08:02
Debido a el discrepancias en grep lo anterior debería ser el patrón preferido si la portabilidad es un problema. - jose hadas
27
Utilice la coincidencia no codiciosa, si su motor lo admite. Añade el ? dentro de la captura.
/location="(.*?)"/
respondido 23 mar '10, 20:03
2
Porque estas usando subpatrón cuantificado y como se describe en Documento de Perl,
De forma predeterminada, un subpatrón cuantificado es "codicioso", es decir, coincidirá con muchas veces como sea posible (dada una ubicación de inicio particular) sin dejar de permitir que el resto del patrón coincida. Si lo quieres para que coincida con el número mínimo de veces posible, siga el cuantificador con a "?" . Tenga en cuenta que los significados no cambian, solo la "codicia":
*? //Match 0 or more times, not greedily (minimum matches)
+? //Match 1 or more times, not greedily
Por lo tanto, para permitir que su cuantificado patrón para hacer una coincidencia mínima, sígalo por ?
:
/location="(.*?)"/
respondido 20 nov., 18:10
2
He aquí otra forma.
Aquí está el que quieres. Esto es vago [\s\S]*?
El primer elemento:
[\s\S]*?(?:location="[^"]*")[\s\S]*
Reemplazar con: $1
Explicacion: https://regex101.com/r/ZcqcUm/2
Para completar, este obtiene el último. Esto es codicioso [\s\S]*
El último artículo:[\s\S]*(?:location="([^"]*)")[\s\S]*
Reemplazar con: $1
Explicacion: https://regex101.com/r/LXSPDp/3
Solo hay una diferencia entre estas dos expresiones regulares y esa es la ?
respondido 30 nov., 19:12
1
Las otras respuestas aquí no explican una solución completa para las versiones de expresiones regulares que no admiten la coincidencia no codiciosa. Los cuantificadores codiciosos (.*?
, .+?
etc) son una extensión de Perl 5 que no es compatible con las expresiones regulares tradicionales.
Si su condición de parada es de un solo carácter, la solución es fácil; en vez de
a(.*?)b
puedes igualar
a[^ab]*b
es decir, especificar una clase de caracteres que excluya los delimitadores inicial y final.
En el caso más general, puede minuciosamente construye una expresión como
start(|[^e]|e(|[^n]|n(|[^d])))end
para capturar una coincidencia entre start
y la primera aparición de end
. Observe cómo la subexpresión con paréntesis anidados detalla una serie de alternativas que entre ellas permiten e
solo si no es seguido por nd
y así sucesivamente, y también tenga cuidado de cubrir la cadena vacía como una alternativa que no coincida con lo que no está permitido en ese punto en particular.
Por supuesto, el enfoque correcto en la mayoría de los casos es usar un analizador adecuado para el formato que está tratando de analizar, pero a veces, tal vez uno no esté disponible, o tal vez la herramienta especializada que está utilizando insiste en una expresión regular y nada demás.
Respondido 08 Jul 20, 19:07
0
import regex
text = 'ask her to call Mary back when she comes back'
p = r'(?i)(?s)call(.*?)back'
for match in regex.finditer(p, str(text)):
print (match.group(1))
Salida: María
Respondido 09 Jul 20, 16:07
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas regex or haz tu propia pregunta.
¿Cuál es tu fuente, es HTML o xml o algo así? - Oskar Kjellin
¿Por qué es esta una wiki comunitaria? Es una pregunta real. Muy tarde ahora. - Ahmad Mageed
¿En qué idioma estás escribiendo? No utilice expresiones regulares para XML. Hay muchas formas mejores de analizar XML: Oskar Kjellin
No si todo lo que desea es buscar atributos simples. Regex es apropiado y más rápido. - codenheim
Yo diría que si, por ejemplo, codificas c #, es mucho mejor usar linq para esto. Dudo que sea mejor usar expresiones regulares si tienes un buen analizador - Oskar Kjellin