Jak mogę usunąć znak z ciągu za pomocą Javascript?


361

Jestem tak blisko zdobycia tego, ale to po prostu nie w porządku. Chciałbym tylko usunąć znak rz łańcucha. Problem polega na tym, że rw łańcuchu występuje więcej niż jedno wystąpienie . Jednak zawsze jest to znak o indeksie 4 (czyli piąty znak).

przykładowy ciąg: crt/r2002_2

Czego chcę: crt/2002_2

Ta funkcja zamiany usuwa oba r

mystring.replace(/r/g, '')

Produkuje: ct/2002_2

Próbowałem tej funkcji:

String.prototype.replaceAt = function (index, char) {
    return this.substr(0, index) + char + this.substr(index + char.length);
}
mystring.replaceAt(4, '')

Działa tylko wtedy, gdy zastąpię go inną postacią. Nie tylko to usunie.

jakieś pomysły?


W czym jest problem, wszystkie „r” zostały usunięte, prawda?
Vladimir Despotovic

Odpowiedzi:


474
var mystring = "crt/r2002_2";
mystring = mystring.replace('/r','/');

zastąpi /rza /pomocą String.prototype.replace.

Alternatywnie możesz użyć wyrażenia regularnego z flagą globalną (zgodnie z sugestią Erika Reppena i Gali Sagar , poniżej), aby zastąpić wszystkie wystąpienia

mystring = mystring.replace(/\/r/g, '/');

EDYCJA: Ponieważ wszyscy dobrze się tutaj bawią, a użytkownik 1293504 nie wydaje się wracać w najbliższym czasie, aby odpowiedzieć na wyjaśnienia pytań, oto metoda usunięcia n-tego znaku z ciągu:

String.prototype.removeCharAt = function (i) {
    var tmp = this.split(''); // convert to an array
    tmp.splice(i - 1 , 1); // remove 1 element from the array (adjusting for non-zero-indexed counts)
    return tmp.join(''); // reconstruct the string
}

console.log("crt/r2002_2".removeCharAt(4));

Ponieważ użytkownik1293504 użył normalnej liczby zamiast liczby zero-indeksowanej, musimy usunąć 1 z indeksu, jeśli chcesz użyć tego do replikacji, w jaki sposób charAtdziała nie odejmowanie 1 od indeksu w 3. linii i użyj tmp.splice(i, 1)zamiast tego.


3
Czwarta postać niekoniecznie jest"/"
jak.b

74

Byłby to prosty funkcjonalny sposób javascript

mystring = mystring.split('/r').join('/')

prosty, szybki, zastępuje globalnie i nie wymaga żadnych funkcji ani prototypów


3
Działa świetnie dla mnie. Podczas gdy próbuję mystring = mystring.replace ('/ r', '/'); konwertuje tylko pierwszy korektor, pozostałe są takie, jakie są.
rb vishnu,

1
Myślę, że to najlepsze rozwiązanie, bardzo proste i nie musisz znać regexu!
Komercyjne samobójstwo

2
Czwarta postać niekoniecznie jest'/'
jak.b

1
tak czy inaczej, zgodnie z testami ( stackoverflow.com/questions/50463850/… ), chyba że piszesz javascript o wysokiej wydajności (10 000 operacji na sekundę) różnica wydajności nie jest problemem ani „wysoką ceną do zapłaty”, więc nie rozumiem, jak dokładnie twój komentarz przyczynić się do rozwiązania
Strife86

Oprócz tego, że jest nieefektywna (a taka funkcja może być używana iteracyjnie na długich listach, gdzie ma to znaczenie), nie odpowiada na pytanie OP, które zależy od indeksu, a nie od poprzedzającego znaku.
aamarks

49

Zawsze są funkcje ciągów, jeśli wiesz, że zawsze usuniesz czwarty znak:

str.slice(0, 4) + str.slice(5, str.length))

Nie działa to przy usuwaniu pierwszej lub ostatniej postaci
TekTimmy

3
@TekTimmy Dlaczego nie? str.slice(0, 0) + str.slice(1, str.length)usuwa pierwszy i str.slice(0, str.length-1) + str.slice(str.length, str.length)usuwa ostatni. (Oczywiście usunąłbyś zbędne części, jeśli wiesz, że zawsze usuwasz pierwszy lub ostatni, ale jeśli są to zmienne, działają tak samo dobrze, jak każdy inny indeks.)
JJJ,

30

Twój pierwszy func jest prawie właściwy. Po prostu usuń flagę „g”, która oznacza „globalny” (edytuj) i daj jej kontekst, by rozpoznał drugą „r”.

Edycja: wcześniej nie widziałem, żeby to był drugi „r”, dlatego dodałem „/”. Potrzebuje \ /, aby uciec przed „/” podczas używania argumentu regEx. Dzięki za opinie, ale się myliłem, więc poprawię i dodam więcej szczegółów dla osób zainteresowanych lepszym zrozumieniem podstaw regEx, ale to zadziała:

mystring.replace(/\/r/, '/')

Teraz nadmierne wyjaśnienie:

Czytając / pisząc wzór regEx, pomyśl w kategoriach: <a znak lub zestaw znaków> następnie znak <a lub zestaw znaków> następnie <...

W regEx <a znak lub zestaw znaków> może być pojedynczo:

/each char in this pattern/

Więc czytaj jako e, następnie a, a następnie c itd.

Lub pojedynczy <a znak lub zestaw znaków> może być znakami opisanymi przez klasę znaków:

/[123!y]/
//any one of these
/[^123!y]/
//anything but one of the chars following '^' (very useful/performance enhancing btw)

Lub rozwinięty, aby dopasować liczbę znaków (ale nadal najlepiej myśleć o nim jako o pojedynczym elemencie pod względem wzoru sekwencyjnego):

/a{2}/
//precisely two 'a' chars - matches identically as /aa/ would

/[aA]{1,3}/
//1-3 matches of 'a' or 'A'

/[a-zA-Z]+/
//one or more matches of any letter in the alphabet upper and lower
//'-' denotes a sequence in a character class

/[0-9]*/
//0 to any number of matches of any decimal character (/\d*/ would also work)

Więc połącz kilka:

   var rePattern = /[aA]{4,8}(Eat at Joes|Joes all you can eat)[0-5]+/g
   var joesStr = 'aaaAAAaaEat at Joes123454321 or maybe aAaAJoes all you can   eat098765';

   joesStr.match(rePattern);

   //returns ["aaaAAAaaEat at Joes123454321", "aAaAJoes all you can eat0"]
   //without the 'g' after the closing '/' it would just stop at the first   match and return:
   //["aaaAAAaaEat at Joes123454321"]

I oczywiście przesadziłem, ale miałem na myśli to, że:

/cat/

to seria 3 elementów wzoru (rzecz, po której następuje rzecz, po której następuje rzecz).

I to jest tak:

/[aA]{4,8}(Eat at Joes|Joes all you can eat)[0-5]+/

Tak dziwaczny, jak regEx zaczyna wyglądać, wszystko rozkłada się na szereg rzeczy (potencjalnie wieloznakowych) następujących po sobie. Niby podstawowy punkt, ale zajęło mi to trochę czasu, więc przesadziłem, tłumacząc to tutaj, ponieważ myślę, że pomógłby OP i innym nowicjuszom w zrozumieniu, co się dzieje. Kluczem do czytania / pisania regEx jest rozbicie go na te kawałki.


13

W przypadku globalnej zamiany „/ r” ten kod działał dla mnie.

mystring = mystring.replace(/\/r/g,'');

8

Po prostu napraw swoje replaceAt:

String.prototype.replaceAt = function(index, charcount) {
  return this.substr(0, index) + this.substr(index + charcount);
}

mystring.replaceAt(4, 1);

Nazwałbym to removeAtzamiast tego. :)


1
To faktycznie rozwiązuje problem PO i ledwo podnosi liczbę głosów, podczas gdy dwie najlepsze odpowiedzi nie rozwiązują pierwotnego pytania!
aamarks

5
return this.substr(0, index) + char + this.substr(index + char.length);

char.lengthwynosi zero. W 1tym przypadku musisz dodać , aby pominąć postać.


To nie odpowiada na zadane pytanie; to po prostu wyjaśnia, dlaczego replaceAtnie działa. Powinien to być komentarz do pierwotnego pytania zamiast odpowiedzi. :)
Ken White

@KenWhite, to rzeczywiście to jest odpowiedź na pytanie tylko zapytać Any thoughts?.
Ash Burlaczenko

Słusznie. Nie zgadzam się, ale ... :) Nie głosowałem, ale nie sądzę, że kwalifikuje się jako odpowiedź. Odpowiedź zapewni rozwiązanie problemu lub przynajmniej wyjaśni bardziej szczegółowo i podpowie, jak go naprawić.
Ken White

@KenWhite, zgadzam się, chciałem tylko powiedzieć, że OP mógł wyjaśnić jego pytanie? Niektórzy ludzie chcą jedynie wskazać kierunek, a nie tylko dać odpowiedź.
Ash Burlaczenko

1
+1 dla @paislee - ta odpowiedź nie jest pomocna, ponieważ w JavaScript nie ma czegoś takiego jak znak.
simpleigh

2

Jeśli zawsze jest to czwarty znak w łańcuchu, możesz spróbować:

yourString.replace(/^(.{4})(r)/, function($1, $2) { return $2; });

2

Działa tylko wtedy, gdy zastąpię go inną postacią. Nie tylko to usunie.

Wynika to z faktu, że gdy charjest równe "", char.lengthwynosi 0, więc podłańcuchy łączą się, tworząc oryginalny ciąg. Idąc z twoją próbą kodu, następujące działania będą działać:

String.prototype.replaceAt = function (index, char) {
    return this.substr(0, index) + char + this.substr(index + 1);
    //   this will 'replace' the character at index with char ^
}

2

Utwórz funkcję jak poniżej

  String.prototype.replaceAt = function (index, char) {
      if(char=='') {
          return this.slice(0,index)+this.substr(index+1 + char.length);
      } else {
          return this.substr(0, index) + char + this.substr(index + char.length);
      }
  }

Aby zastąpić, podaj znak jak poniżej

  var a="12346";
  a.replaceAt(4,'5');

wprowadź opis zdjęcia tutaj

i aby usunąć znak przy określonym indeksie, podaj drugi parametr jako pusty ciąg

a.replaceAt(4,'');

wprowadź opis zdjęcia tutaj


2

Jeśli chcesz usunąć pojedynczy znak i jeśli znasz indeks znaku, który chcesz usunąć, możesz użyć następującej funkcji:

/**
 * Remove single character at particular index from string
 * @param {*} index index of character you want to remove
 * @param {*} str string from which character should be removed
 */
function removeCharAtIndex(index, str) {
    var maxIndex=index==0?0:index;
    return str.substring(0, maxIndex) + str.substring(index, str.length)
}

W niektórych przypadkach nie zadziała (np. Indeks = 0).
Tomer,

1

Nie lubię używać funkcji replace do usuwania znaków z łańcucha. Nie jest to logiczne, aby robić to w ten sposób. Zwykle programuję w języku C # (Sharp) i za każdym razem, gdy chcę usunąć znaki z łańcucha znaków, używam metody Remove klasy String, ale nie metody Replace, nawet jeśli istnieje, ponieważ kiedy mam zamiar usunąć, usuwam, bez zamiany. To jest logiczne!

W JavaScript nie ma funkcji usuwania ciągu, ale jest funkcja substr. Możesz użyć funkcji substr raz lub dwa razy, aby usunąć znaki z łańcucha. Można wykonać następującą funkcję, aby usunąć znaki przy indeksie początkowym do końca łańcucha, podobnie jak metoda przeciążająca najpierw metodę C # String.Remove (int startIndex):

function Remove(str, startIndex) {
    return str.substr(0, startIndex);
}

i / lub możesz również wykonać następującą funkcję usuwania znaków przy indeksie początkowym i liczeniu, podobnie jak w przypadku drugiego przeciążenia metody c # String.Remove (int startIndex, int count):

function Remove(str, startIndex, count) {
    return str.substr(0, startIndex) + str.substr(startIndex + count);
}

a następnie możesz użyć tych dwóch funkcji lub jednej z nich do własnych potrzeb!

Przykład:

alert(Remove("crt/r2002_2", 4, 1));

Wyjście: crt / 2002_2

Osiąganie celów za pomocą technik bez logiki może powodować nieporozumienia w zrozumieniu kodu i przyszłe błędy, jeśli robisz to dużo w dużym projekcie!


2
Powiedziałbym, że wprowadzenie obcych metod jest znacznie bardziej mylące niż samo używanie String.prototype.replace, które jest częścią podstawowego API. Co więcej, rozumienie usuwania jako szczególnego przypadku zastąpienia jest dość logiczne, jeśli chodzi o programowanie. Nie powinieneś próbować, aby twój API zawierał wszystkie słowa ze słownika angielskiego, powinieneś spróbować zredukować swój API do minimalnej ortogonalnej podstawy.
Witiko

1

Następująca funkcja działała najlepiej w moim przypadku:

public static cut(value: string, cutStart: number, cutEnd: number): string {
    return value.substring(0, cutStart) + value.substring(cutEnd + 1, value.length);
}

1

Najkrótszym sposobem byłoby użycie splajnu

var inputString = "abc";
// convert to array and remove 1 element at position 4 and save directly to the array itself
let result = inputString.split("").splice(3, 1).join();
console.log(result);

Splice mutuje oryginalną tablicę i zwraca tylko wykonane elementy. Ponieważ tablice mają indeksy zerowe, ten przykład zwróci „” (ponieważ trzeci element w tablicy jest pustym miejscem między ci ")
JKirchartz 12.09.19

1

Możesz użyć tego: if ( str[4] === 'r' ) str = str.slice(0, 4) + str.slice(5)

Wyjaśnienie:

  1. if ( str[4] === 'r' )
    Sprawdź, czy piąty znak to 'r'

  2. str.slice(0, 4)
    Pokrój ciąg, aby uzyskać wszystko przed 'r'

  3. + str.slice(5)
    Dodaj resztę ciągu.

Zminimalizowane: s=s[4]=='r'?s.slice(0,4)+s.slice(5):s [37 bajtów!]

DEMO:

function remove5thR (s) {
  s=s[4]=='r'?s.slice(0,4)+s.slice(5):s;
  console.log(s); // log output
}

remove5thR('crt/r2002_2')  // > 'crt/2002_2'
remove5thR('crt|r2002_2')  // > 'crt|2002_2'
remove5thR('rrrrr')        // > 'rrrr'
remove5thR('RRRRR')        // > 'RRRRR' (no change)


1
let str = '1234567';
let index = 3;
str = str.substring(0, index) + str.substring(index + 1);
console.log(str) // 123567 - number "4" under index "3" is removed


-1

W C # (Sharp) możesz utworzyć pusty znak jako „\ 0”. Może możesz to zrobić:

String.prototype.replaceAt = function (index, char) {
return this.substr(0, index) + char + this.substr(index + char.length);
}
mystring.replaceAt(4, '\0')

Szukaj w Google lub surfuj po Internecie i sprawdź, czy javascript pozwala tworzyć puste znaki, podobnie jak C #. Jeśli tak, dowiedz się, jak to zrobić, a może funkcja replaceAt w końcu zadziała, a osiągniesz to, co chcesz!

Wreszcie ta postać „r” zostanie usunięta!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.