2011-03-28 15 views
11

Tengo que eliminar la cadena entre dos delimitadores, es decir, De "123XabcX321" Quiero "123321". Para un caso sencillo, estoy bien con:"ansioso" expresión regular que coincida con

$_=<>; 
s/X(.*)X//; 
print; 

Pero si hay ambigüedad en la entrada como "123XabcXasdfjXasdX321", que coincide con el primer X con el último X y me sale "123321" pero quiero " 123asdfj321 ". ¿Hay alguna manera de especificar una coincidencia "ansiosa" que coincida con el primer delimitador válido válido y no el último?

Respuesta

28

Normalmente se llama "poco codicioso", pones un? después del cuantificador: s/X(.*?)X//;

+1

y en el ejemplo dado, se necesitaría/g para sustituirlo más de una vez. – ysth

+0

Creo que "no codicioso" es el término más común. En cualquier caso, el valor predeterminado es concordancia codiciosa, y quieres lo contrario. – cjm

+0

gracias, eso era lo que estaba buscando – GClaramunt

6

Evite el modificador no codicioso como algo más que una sugerencia de rendimiento si puede. Su uso puede generar resultados "inesperados" porque agregar ? en realidad no impide que .* coincida con nada. Por ejemplo,

$ perl -le'print for "XaXbXY" =~ /X(.*?)XY/;' 
aXb 

Para evitar que emparejan X, puede utilizar el siguiente:

s/X[^X]*X//g; 

Si X es realmente algo más grande que un personaje, puede utilizar el siguiente:

s/X(?:(?!X).)*X//g; 
+0

interesante ... Lo intentaré. En mi caso, la X es más de un char. Tendré que descifrar? :(?! X) tho – GClaramunt

+0

@GClaramunt, '(?:)' En patrones regex son como '()' en Perl. En este caso, indica que '*' afecta a '(?! X) .' en lugar de simplemente' .'. '()' se usa con frecuencia para este propósito. – ikegami

+0

@GClaramunt, '(?!)' Verifica que lo que sigue no coincida con el patrón contenido. – ikegami

Cuestiones relacionadas