2012-02-25 9 views
5

estoy usando una expresión regular para encontrar:Regex lookAhead

test:? 

seguido de cualquier carácter hasta de que llegue el siguiente:

test:? 

Ahora en que funciono esta expresión regular que hice:

((?:test:\?)(.*)(?!test:\?)) 

En este texto:

test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2 

que espera conseguir:

test:?foo2=bar2&baz2=foo2 

test:?foo=bar&baz=foo 

test:?foo2=bar2&baz2=foo2 

Pero en lugar de que coincide todo. ¿Alguien con más experiencia en expresiones regulares sabe dónde me he equivocado? He usado expresiones regulares para la coincidencia de patrones antes, pero esta es mi primera experiencia con lookarounds/aheads.

Gracias de antemano por cualquier ayuda/consejos/punteros :-)

+0

simplemente que desean dividir en 'test:?'? Si es así, su entorno proporcionará una forma de hacerlo sin expresiones regulares. –

Respuesta

4

Supongo que podría explorar una versión codiciosa.
(ampliado)

(test:\? (?: (?!test:\?)[\s\S])*)

+0

Gracias. Esto funcionó perfectamente y aprendí más sobre la sintaxis. – james

-1

es probable que desee ((?:test:\?)(.*?)(?=test:\?)), a pesar de que no nos ha dicho qué idioma se utiliza para conducir las expresiones regulares.

Los partidos .*? el menor número de caracteres posible sin impedir a toda la cadena de juego, donde .* partidos tantos como sea posible (es codicioso).

Depende, de nuevo, del idioma que está usando para hacer esto, probablemente necesite hacer coincidir, luego cortar la cadena, volver a hacer coincidir o llamar a alguna función de tipo match_all específica del idioma.

Por cierto, no es necesario para anclar una expresión regular usando una búsqueda hacia delante (sólo puede coincidir con el patrón a buscar, en su lugar), por lo que este va (lo más probable) hacer en su caso:

test:[?](.*?)test:[?] 
+1

Si va a tomar ese enfoque, entonces necesita cambiar el '?!' A '? ='. – ruakh

+0

@ruakh Derecha. Cambiado, gracias. – Borealid

+1

-1, se necesita un seguimiento. Sin él, ninguna otra coincidencia requerida no coincidiría porque 'test:' ya se había consumido. – Qtax

0

tres cuestiones:

  • (?!) es una afirmación de búsqueda negativa hacia delante. Desea (?=) en su lugar, requiriendo que lo que sigue sea test:?.

  • El .* es codicioso; lo quieres no codicioso para que agarres solo el primer trozo.

  • Usted está queriendo el último trozo también, entonces usted quisiera emparejar $ también al final.

Resultado final:

(?:test:\?)(.*?)(?=test:\?|$) 

también he eliminado el grupo externo, ya no tiene sentido en ella. Todos los motores de RE que conozco te permiten acceder al grupo 0 como la coincidencia completa, o de alguna otra manera (aunque quizás no al encontrar todas las coincidencias). Puede volver a colocarlo si lo necesita.

(esto funciona en PCRE; no está seguro de si funcionaría con expresiones regulares POSIX, ya que no estoy en el hábito de trabajar con ellos.)

Si acaba de querer dividir en test:?, sin embargo, las expresiones regulares son la herramienta incorrecta. Divida las cadenas utilizando el soporte incorporado de su idioma para tales cosas.

Python:

>>> re.findall('(?:test:\?)(.*?)(?=test:\?|$)', 
... 'test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2') 
['foo2=bar2&baz2=foo2', 'foo=bar&baz=foo', 'foo2=bar2&baz2=foo2'] 
2

El programa Perl debajo

#! /usr/bin/env perl 

use strict; 
use warnings; 

$_ = "test:?foo2=bar2&baz2=foo2test:?foo=bar&baz=footest:?foo2=bar2&baz2=foo2"; 

while (/(test:\? .*?) (?= test:\? | $)/gx) { 
    print "[$1]\n"; 
} 

produce la salida deseada de su pregunta, además de los soportes para el énfasis.

[test:?foo2=bar2&baz2=foo2] 
[test:?foo=bar&baz=foo] 
[test:?foo2=bar2&baz2=foo2]

Recuerde que regex quantifiers are greedy y quieren engullir todo lo que pueda, sin romper el partido. Cada subsegmento terminará tan pronto como sea posible, lo que significa .*? semántica.

Cada subsegmento termina ya sea con otro test:? o al final de la cadena, que buscamos con (?=...) lookahead cero-anchura envuelto alrededor de | alternativas.

El patrón en el código anterior usa Perl’s /x regex switch para facilitar la lectura. Dependiendo del idioma y las bibliotecas que esté usando, puede que necesite quitar el espacio en blanco adicional.

+0

Utilicé su sytnax en un probador de expresiones regulares pero el emparejamiento aún me dio una cadena que contenía dos "pruebas :?" instrumentos de cuerda. Estoy usando Java así que supongo que podría estar relacionado con la sintaxis. (Eliminé los espacios en blanco para la prueba). Gracias por su ayuda, aunque aprendí mucho más. – james

Cuestiones relacionadas