Jak zamienić wszystkie kropki w ciągu za pomocą JavaScript


426

Chcę zastąpić wszystkie wystąpienia kropki (. ) w ciągu JavaScript

Mam na przykład:

var mystring = 'okay.this.is.a.string';

Chcę dostać: okay this is a string.

Do tej pory próbowałem:

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

ale kończy się to tym, że cały ciąg zostaje zastąpiony spacjami.


8
Odpowiedź aefxx jest prawidłowa, ale tak jak w przypadku FYI to, że znak okresu w wyrażeniu regularnym oznacza dopasowanie wszystkiego , a więc wszystko jest spacją. Ucieczka z odwrotnym ukośnikiem oznacza dopasowanie w kropkach.
swilliams

Dzięki za wskazówkę. Mam kilka chwil AHA (podczas tworzenia aplikacji) z Regex. Nienawidzę go _ , masz jakieś fajne, dobry tutorial?
Omar Abid

rubular.com jest tym, czego szukasz
LanguagesNamedAfterCofee

1
Nie używaj wyrażenia regularnego dla czegoś tak trywialnego.
Steven Lu

Niestety nie wygląda na to, że wyrażenie niebędące wyrażeniem regularnym może wielokrotnie zastępować ciąg.
Steven Lu

Odpowiedzi:


777

Musisz uciec przed, .ponieważ ma on znaczenie „dowolnego znaku” w wyrażeniu regularnym.

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

25
dla wyjaśnienia, \ unika znaków specjalnych w wyrażeniach regularnych, takich jak. w tym przypadku
realgt

wygląda jak sed .. jakoś .. :)
Paschalis

w wyrażeniu reagukar kropka. oznacza wszystko, to jest właściwe rozwiązanie!
Benjamin Fuentes,

1
@Kingalione Co dokładnie nie działa? Czy mógłbyś opracować?
aefxx

1
@Webwoman Do tego służy gmodyfikator na końcu wyrażenia. Pomyśl o tym jak (g) lobalnie.
aefxx,

301

Jeszcze jedno łatwe do zrozumienia :)

var newstring = mystring.split('.').join(' ');

25
@HaggleLad, ponieważ nie musisz zadzierać z regex
ton.yeung

5
Czy to nie jest dużo wolniejsze od wyrażania regularnego?
Jasper Kennis

1
@Jasper z mojego zrozumienia, w rzeczywistości jest szybszy w większości przeglądarek, chociaż sam nie przeprowadziłem testów porównawczych.
andrew

9
@BetoFrega Nic nie przypomina danych empirycznych, które uzasadniają Twoją sprawę :). Dziękujemy za podanie linku!
testowanie123

3
Jeśli używasz RegExp, chcesz przechowywać regex w osobnej zmiennej poza pętlą. Kompilacja / interpretacja wyrażenia regularnego zajmuje trochę czasu, ale po skompilowaniu można go używać dość szybko. Spróbuj wykonać te testy, które wykonałem: jsperf.com/replace-vs-split-join-vs-replaceall/23
sanderd17

53
/**
 * ReplaceAll by Fagner Brack (MIT Licensed)
 * Replaces all occurrences of a substring in a string
 */
String.prototype.replaceAll = function( token, newToken, ignoreCase ) {
    var _token;
    var str = this + "";
    var i = -1;

    if ( typeof token === "string" ) {

        if ( ignoreCase ) {

            _token = token.toLowerCase();

            while( (
                i = str.toLowerCase().indexOf(
                    _token, i >= 0 ? i + newToken.length : 0
                ) ) !== -1
            ) {
                str = str.substring( 0, i ) +
                    newToken +
                    str.substring( i + token.length );
            }

        } else {
            return this.split( token ).join( newToken );
        }

    }
return str;
};

alert('okay.this.is.a.string'.replaceAll('.', ' '));

Szybszy niż użycie wyrażenia regularnego ...

EDYTOWAĆ:
Może w czasie, gdy tworzyłem ten kod, nie używałem jsperf. Ale w końcu taka dyskusja jest całkowicie bezcelowa, różnica w wydajności nie jest warta czytelności kodu w świecie rzeczywistym, więc moja odpowiedź jest nadal aktualna, nawet jeśli wydajność różni się od podejścia wyrażenia regularnego.

EDIT2:
Stworzyłem bibliotekę, która pozwala ci to robić za pomocą płynnego interfejsu:

replace('.').from('okay.this.is.a.string').with(' ');

Zobacz https://github.com/FagnerMartinsBrack/str-replace .


1
Bardzo przydatne. Do waszej wiadomości: W oświadczeniu ostrzegawczym znajdują się nieuczciwe postacie po średniku.
Patrick

Co masz na myśli mówiąc o „nieuczciwej postaci”?
Fagner Brack

1
On oznacza byt & # 8203; dwa razy, czyli znak Unicode „ZERO WIDTH SPACE” (U + 200B). Więcej informacji na temat fileformat.info/info/unicode/char/200b/index.htm
Cur

@FagnerBrack Prawdopodobnie powinieneś wyjść str.toLowerCase()poza pętlę ze względu na wydajność. Ponadto manipulowanie ciągiem, którego szukasz, jest prawdopodobnie mniej niż optymalne. Odpowiedziałem w zmodyfikowanej wersji: stackoverflow.com/questions/2390789/...
sstur

@sstur Podejrzewam, że po manipulacji wymagane jest ponowne małe litery. Czy manipulowanie ciągiem, którego szukam, ma znaczącą różnicę w wydajności? Podejrzewam, że czytelność przewyższa korzyści (niesprawdzone).
Fagner Brack


15

W tym prostym scenariuszu zaleciłbym również użycie metod, które są wbudowane w javascript.

Możesz spróbować:

"okay.this.is.a.string".split(".").join("")

Pozdrowienia


6

Do kropki dodaję podwójny ukośnik odwrotny, aby działał. Dopingować.

var st = "okay.this.is.a.string";
var Re = new RegExp("\\.","g");
st = st.replace(Re," ");
alert(st);

4

Jest to bardziej zwięzłe / czytelne i powinno działać lepiej niż to opublikowane przez Fagner Brack (toLowerCase nie jest wykonywane w pętli):

String.prototype.replaceAll = function(search, replace, ignoreCase) {
  if (ignoreCase) {
    var result = [];
    var _string = this.toLowerCase();
    var _search = search.toLowerCase();
    var start = 0, match, length = _search.length;
    while ((match = _string.indexOf(_search, start)) >= 0) {
      result.push(this.slice(start, match));
      start = match + length;
    }
    result.push(this.slice(start));
  } else {
    result = this.split(search);
  }
  return result.join(replace);
}

Stosowanie:

alert('Bananas And Bran'.replaceAll('An', '(an)'));

1
Właściwie wydaje się, że uciekł RegEx działa lepiej niż indexOf! Nie brzmi dobrze, ale JSPerf wskazuje, że jest znacznie szybszy: jsperf.com/replaceall-indexof-vs-regex
sstur

Może w czasie, gdy tworzyłem ten kod, nie używałem jsperf. Ale ostatecznie taka dyskusja jest całkowicie bezcelowa, różnica w wydajności nie jest warta czytelności kodu w świecie rzeczywistym, więc moja odpowiedź jest nadal aktualna.
Fagner Brack

2
String.prototype.replaceAll = function(character,replaceChar){
    var word = this.valueOf();

    while(word.indexOf(character) != -1)
        word = word.replace(character,replaceChar);

    return word;
}

3
czy to nie utknie w nieskończonej pętli, jeśli dasz mu coś takiego replaceAll('&', '&'):? (co prawda nie jest to kwestia pytania OP)
Anentropic

Ale „& amp;” zawiera &tak, że w pętli nigdy nie zabraknie rzeczy do zastąpienia (a ciąg ciągle rośnie). Właśnie tego spróbowałem i to zablokowało moją przeglądarkę ...
Anentropic

2

Oto kolejna implementacja replaceAll. Mam nadzieję, że to komuś pomoże.

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if (stringToFind === stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };

Następnie możesz go użyć:

var myText = "Nazywam się George";
var newText = myText.replaceAll („George”, „Michael”);


1
Nie obsługuje to wyszukiwania / zamiany bez rozróżniania wielkości liter. Jest to funkcjonalnie równoważne z:string.split(stringToFind).join(stringToReplace)
sstur

0

Przykład: Chcę zamienić wszystkie podwójne cudzysłowy („) na pojedyncze cudzysłowy ('). Wtedy kod będzie taki

var str= "\"Hello\""
var regex = new RegExp('"', 'g');
str = str.replace(regex, '\'');
console.log(str); // 'Hello'

0

@ scripto jest nieco bardziej zwięzłe i bez prototype:

function strReplaceAll(s, stringToFind, stringToReplace) {
    if (stringToFind === stringToReplace) return s;
    for (let index = s.indexOf(stringToFind); index != -1; index = s.indexOf(stringToFind))
        s = s.replace(stringToFind, stringToReplace);
    return s;
}

Oto, jak się układa: http://jsperf.com/replace-vs-split-join-vs-replaceall/68


0
String.prototype.replaceAll = function (needle, replacement) {
    return this.replace(new RegExp(needle, 'g'), replacement);
};


-1

można zastąpić wszystkie wystąpienia dowolnego łańcucha / znaku przy użyciu obiektu javasscript RegExp.

Oto kod

var mystring = 'okay.this.is.a.string';

var patt = new RegExp("\\.");

while(patt.test(mystring)){

  mystring  = mystring .replace(".","");

}

-5
var mystring = 'okay.this.is.a.string';
var myNewString = escapeHtml(mystring);

function escapeHtml(text) {
if('' !== text) {
    return text.replace(/&/g, "&")
               .replace(/&lt;/g, "<")
               .replace(/&gt;/g, ">")
               .replace(/\./g,' ')
               .replace(/&quot;/g, '"')
               .replace(/&#39/g, "'");
} 

Aby uniknąć HTML, użyjcreateTextNode
Downgoat
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.