2012-03-14 35 views

Respuesta

8

2-liner:

function removeAllButLast(string, token) { 
    /* Requires STRING not contain TOKEN */ 
    var parts = string.split(token); 
    return parts.slice(0,-1).join('') + token + parts.slice(-1) 
} 

versión alternativa sin el requisito en el argumento de cadena:

function removeAllButLast(string, token) { 
    var parts = string.split(token); 
    if (parts[1]===undefined) 
     return string; 
    else 
     return parts.slice(0,-1).join('') + token + parts.slice(-1) 
} 

Demostración:

> removeAllButLast('a.b.c.d', '.') 
"abc.d" 

La siguiente de una sola línea es una expresión regular que se lleva ventaja del hecho de que el carácter * es codicioso, y que reemplazará dejará la cuerda sola si no se encuentra una coincidencia. Se hace coincidir [cadena más larga que incluye puntos] [punto] y dejando [resto de cadena], y si se encuentra una coincidencia se despoja de todo' es de ella:.

'a.b.c.d'.replace(/(.*)\./, x => x.replace(/\./g,'')+'.') 

(Si la cadena contiene saltos de línea , tendrá que usar [.\n] en lugar de . desnudos

+0

solo para obtener información: si alguien necesita eliminar todo menos primero, use >>> la función removeAllButFirst (cadena, token) { var parts = string.split (token); return parts.slice (0,1) + token + parts.slice (1) .join (''); } – UsmanShabbir

+1

información adicional, si la cadena no contiene el token, se agregará. – Ello

+0

@Ello: gracias por encontrar eso, solución adicional y también un método de expresión regular. – ninjagecko

0

Se podría revertir la cadena, eliminar todas las apariciones de la subcadena, excepto el primero, y revertir de nuevo para obtener lo que desea.

+0

le hace pensar que la eliminación de todas las ocurrencias excepto el primero es más fácil y luego al revés? – Raynos

+1

recorriendo la cadena, es más fácil mantener una bandera para saber que la primera ha pasado, y podemos proceder a eliminar todas las ocurrencias ahora. Más fácil y más legible que invertir el bucle a través de la cadena utilizando el método str.charAt. Siempre puede recordar la ubicación de la última ocurrencia utilizando str.lastIndexOf, pero esa ubicación seguirá cambiando a medida que elimina cualquier subcadena que ocurra antes, por lo que debe volverse a calcular. – swapz83

+0

Un ciclo hacia atrás es mejor que dos llamadas para invertir – Raynos

5

Usted puede hacer algo como esto:

var str = '1.2.3.4'; 
var last = str.lastIndexOf('.'); 
var butLast = str.substring(0, last).replace(/\./g, ''); 
var res = butLast + str.substring(last); 

ejemplo vivo:

0
function formatString() { 
    var arr = ('1.2.3.4').split('.'); 
    var arrLen = arr.length-1; 
    var outputString = '.' + arr[arrLen]; 
    for (var i=arr.length-2; i >= 0; i--) { 
    outputString = arr[i]+outputString; 
    } 
    alert(outputString); 
} 

verlo en acción aquí: http://jsbin.com/izebay

1

var s = '1.2.3.4';

s=s.split('.'); 
s.splice(s.length-1,0,'.'); 
s.join(''); 

123,4

8

Puede utilizar expresiones regulares con mirada positiva hacia el futuro,

"1.2.3.4".replace(/[.](?=.*[.])/g, ""); 
+1

Esta debería ser la respuesta aceptada. Para decir esto en inglés, la expresión regular dice "hacer coincidir todas las apariciones de. Que tienen otra. Después de ellas", luego simplemente la reemplaza con una cadena vacía. Escuchará quejas ocasionales de que la expresión regular no es tan legible como hacer una gran división luego formatearla de la matriz, pero es bastante fácil describir su expresión regular en un comentario sobre ella. –

+0

No creo que sea prudente poner demasiado stock en las pruebas de rendimiento aisladas que el motor no será tan inteligente de optimizar, pero el aspecto positivo no parece escalar tan bien. Aquí encontré que es bastante más rápido para cadenas cortas (el ejemplo '1.2.3.4') que para dividir la matriz, pero está muy rezagado en cadenas más largas: https://jsperf.com/removing-all-but-last-string -simbólico –

0

Una función replaceAllButLast es más útil que una función removeAllButLast. Cuando se desea eliminar simplemente reemplazar con una cadena vacía:

function replaceAllButLast(str, pOld, pNew) { 
 
    var parts = str.split(pOld) 
 
    if (parts.length === 1) return str 
 
    return parts.slice(0, -1).join(pNew) + pOld + parts.slice(-1) 
 
} 
 

 
var test = 'hello there hello there hello there' 
 
test = replaceAllButLast(test, ' there', '') 
 

 
console.log(test) // hello hello hello there

0

encontrado una mejor forma de hacer esto. Aquí está replaceAllButLast y appendAllButLast, ya que deben hacerse. Este último hace un reemplazo mientras conserva la coincidencia original.Para eliminar, simplemente reemplace con una cadena vacía.

var str = "hello there hello there hello there" 
 

 
function replaceAllButLast(str, regex, replace) { 
 
    var reg = new RegExp(regex, 'g') 
 
    return str.replace(reg, function(match, offset, str) { 
 
     var follow = str.slice(offset); 
 
     var isLast = follow.match(reg).length == 1; 
 
     return (isLast) ? match : replace 
 
    }) 
 
} 
 

 
function appendAllButLast(str, regex, append) { 
 
    var reg = new RegExp(regex, 'g') 
 
    return str.replace(reg, function(match, offset, str) { 
 
     var follow = str.slice(offset); 
 
     var isLast = follow.match(reg).length == 1; 
 
     return (isLast) ? match : match + append 
 
    }) 
 
} 
 

 
var replaced = replaceAllButLast(str,/there/, ' world') 
 
console.log(replaced) 
 

 
var appended = appendAllButLast(str,/there/, ' fred') 
 
console.log(appended)

Gracias a @leaf de estas obras maestras que dio here.

0

Puede tener una visión positiva (para conservar el último punto, si corresponde) y reemplazar los primeros puntos que vienen.

var string = '1.2.3.4'; 
 

 
console.log(string.replace(/\.(?=.*\.)/g, ''));

Cuestiones relacionadas