2012-06-21 7 views
47

que tiene un nombre de archivo que puede tener varios puntos en él y podría acabar con cualquier extensión:expresión regular que concuerda la última ocurrencia de punto en una cadena

tro.lo.lo.lo.lo.lo.png 

Tengo que utilizar una expresión regular para reemplazar el último ocurrencia del punto con otra cadena como @2x y luego el punto de nuevo (muy parecido a un nombre de archivo de imagen de la retina), es decir:

tro.lo.png -> [email protected] 

Esto es lo que tengo hasta ahora pero no va a coincidir con cualquier cosa ...

str = "http://example.com/image.png"; 
str.replace(/.([^.]*)$/, " @2x."); 

alguna sugerencia?

+0

Necesita una búsqueda negativa si desea hacerlo con expresiones regulares, pero realmente no debería –

Respuesta

83

No necesita una expresión regular para esto. String.lastIndexOf va a hacer.

var str = 'tro.lo.lo.lo.lo.lo.zip'; 
var i = str.lastIndexOf('.'); 
if (i != -1) { 
    str = str.substr(0, i) + "@2x" + str.substr(i); 
} 

See it in action.

Actualización: Una solución de expresiones regulares, sólo por el gusto de hacerlo:

str = str.replace(/\.(?=[^.]*$)/, "@2x."); 

coincide con un punto literal y luego afirma ((?=) se positive lookahead) que ningún otro personaje hasta el final de la cadena es un punto. El reemplazo debe incluir el único punto coincidente, a menos que desee eliminarlo.

+0

Eso devuelve un número entero de la posición donde está ese personaje, ¿verdad? – alt

+0

¿Cómo puedo usar ese entero con .replace()? – alt

+0

@gdoron: Estaba trabajando en eso :) – Jon

1

Use \. para que coincida con un punto. El carácter . coincide con cualquier carácter.

Por lo tanto str.replace(/\.([^\.]*)$/, ' @2x.').

+1

Pruebe su código: '" tro.lo.lo.lo.lo.lo.zip ".replace (/ \. ([^\.] *) $ /, '@ 2x.') 'No funciona. Lo siento. – gdoron

+0

Genial, no sabía eso sobre la expresión regular – alt

+0

@Jon. ¿Decir ah? . . . . – gdoron

5

Puede utilizar la expresión \.([^.]*?):

str.replace(/\.([^.]*?)$/, "@2x.$1"); 

Es necesario hacer referencia a la $1 subgrupo para copiar la parte posterior en la cadena resultante.

+0

Creo que esto necesita otro período al final de "$ 1 @ 2x" para funcionar, ¿verdad? – alt

+0

Fue un poco apresurado con esa respuesta - se arregló para que tenga más sentido w.r.t. su regex original – rfw

+0

Creo que le falta un '.' en la cadena de reemplazo. Prefiero escapar '.', pero la clase de personaje puede ser más fácil de leer. '.replace (/(.*)\./," $ 1 @ 2x. ")'. De todos modos, +1 para una solución simple usando la propiedad codiciosa del cuantificador '*'. – nhahtdh

4

demostración de trabajohttp://jsfiddle.net/AbDyh/1/

código

var str = 'tro.lo.lo.lo.lo.lo.zip', 
    replacement = '@2x.'; 
str = str.replace(/.([^.]*)$/, replacement + '$1'); 

$('.test').html(str); 

alert(str); 
​ 
+1

No del todo. a la salida le falta un punto. – gdoron

+0

@gdoron lo consiguió: http://jsfiddle.net/AbDyh/1/ ¡Gracias bruvnic! –

+1

** La salida debería ser ** 'tro.lo.lo.lo.lo.lo @ 2x.zip' ** Salidas **' tro.lo.lo.lo.lo.lo @ 2xzip' – gdoron

23

Sólo tiene que utilizar special replacement pattern$1 en la cadena de reemplazo:

console.log("tro.lo.lo.lo.lo.lo.png".replace(/\.([^.]+)$/, "@2x.$1")); 
 
// "[email protected]"

+1

Responde correctamente a la pregunta de OPs. – Qtax

+1

@Qtax: No del todo, porque no funcionará si el último punto es también el último carácter. – Jon

+0

@Jon, cierto. Casi corrige entonces. ;) Pero '/\.([^.]*)$/' lo hace, no hay necesidad de buscar soluciones. – Qtax

2

para que coincida con todos los caracteres desde el comienzo de la cuerda hasta (e incluyendo) la última ocurrencia de un uso personaje:

^.*\.(?=[^.]*$) To match the last occurrence of the "." character 

^.*_(?=[^.]*$) To match the last occurrence of the "_" character 
0

¿Por qué no simplemente dividir la cadena y añadir dicho sufijo a la segunda a la última entrada:

var arr = 'tro.lo.lo.lo.lo.lo.zip'.split('.'); 
arr[arr.length-2] += '@2x'; 
var newString = arr.join('.'); 
Cuestiones relacionadas