2012-03-14 24 views

Odpowiedz

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) 
} 

wersja alternatywna bez wymogu na argumencie:

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) 
} 

Demo:

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

Poniżej jedna wkładka jest wyrażenie regularne, które trwa zaletą tego, że postać * jest chciwa, a ta zamiana pozostawi ciąg w spokoju, jeśli nie zostanie znaleziony żaden pasujący element. Działa poprzez dopasowanie [najdłuższy łańcuch w tym kropek] [dot] i [pozostawiając resztę ciąg], a jeśli zostanie znaleziony to pozbawia wszystkich”Jest z nim.

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

(Jeśli ciąg zawiera znaki nowej linii , będziesz musiał użyć [.\n] zamiast nagiego . s)

+0

tylko po informacje: jeśli ktoś musi usunąć wszystko oprócz pierwszej, użyj >>> funkcji removeAllButFirst (ciąg, token) { var parts = string.split (token); return parts.slice (0,1) + token + parts.slice (1) .join (''); } – UsmanShabbir

+1

dodatkowe informacje, jeśli ciąg nie zawiera tokena, zostanie on dodany. – Ello

+0

@ ALlo: dzięki za znalezienie tego, dodano poprawkę, a także metodę wyrażeń regularnych. – ninjagecko

0

Można odwrócić ciąg, usunąć wszystkie wystąpienia podciągu z wyjątkiem pierwszego i odwrócić go ponownie, aby dostać to, czego chcesz.

+0

Dlaczego myślisz, że usunięcie wszystkich wystąpień wyjątkiem pierwszego jest łatwiej potem na odwrót? – Raynos

+1

zapętlając strunę, łatwiej jest utrzymać flagę, aby wiedzieć, że pierwszy minął, i możemy przystąpić do usuwania wszystkich wystąpień teraz. Łatwiejsze i bardziej czytelne niż odwrotne zapętlenie ciągu znaków za pomocą metody str.charAt. Zawsze możesz zapamiętać lokalizację ostatniego wystąpienia, używając str.lastIndexOf, ale ta lokalizacja będzie się zmieniać wraz z usuwanymi wcześniejszymi podciągami, więc musi zostać ponownie obliczona. – swapz83

+0

Pętla do tyłu jest lepsza niż dwie rozmowy do odwrócenia – Raynos

5

można zrobić coś takiego:

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

żywo przykład:

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); 
} 

Zobacz go w akcji tutaj: 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

Można użyć wyrażenia regularnego z pozytywnego spojrzenia w przyszłość,

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

To powinna być zaakceptowana odpowiedź. Aby powiedzieć to po angielsku, wyrażenie regularne mówi "dopasuj wszystkie wystąpienia., Które mają inne, po nich", po prostu zamień na pusty ciąg. Usłyszysz sporadyczne skargi, że wyrażenie regularne nie jest tak czytelne jak zrobienie dużego podziału, a następnie formatowanie z tablicy, ale dość łatwo jest po prostu opisać swoje wyrażenie w komentarzu nad nim. –

+0

Nie wydaje mi się, żeby rozsądnie było umieścić zbyt wiele akcji w odizolowanych testach wydajności, aby silnik nie był tak inteligentny w optymalizowaniu, ale pozytywny poprzednik nie wydaje się skalować tak ładnie. Zauważyłem, że jest to nieco szybsze w przypadku krótkich łańcuchów (przykład "1.2.3.4"), a nie w porównaniu z podziałem tablicy, ale pozostaje w tyle w przypadku dłuższych łańcuchów: https://jsperf.com/removing-all- but-last-string -znak –

0

replaceAllButLast funkcja jest bardziej przydatna niż removeAllButLast funkcji. Jeżeli chcesz usunąć tylko zastąpić pustym ciągiem:

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

Znaleziony znacznie lepszy sposób to robi. Oto replaceAllButLast i appendAllButLast, ponieważ powinny zostać wykonane. Ten ostatni zastępuje, zachowując oryginalny mecz.Aby usunąć, po prostu zastąp pusty ciąg.

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)

Dzięki @leaf dla tych arcydzieł, które dał here.

0

Można przyjąć pozytywny uprzedzający (dla zachowania ostatniej kropki, jeśli istnieje) i zastąpić pierwsze nadchodzące kropki.

var string = '1.2.3.4'; 
 

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

Powiązane problemy