458

I have a string that contains multiple spaces. I want to replace these with a plus symbol. I thought I could use

var str = 'a b c';
var replaced = str.replace(' ', '+');

but it only replaces the first occurrence. How can I get it replace all occurrences?

Cœur
  • 37,241
  • 25
  • 195
  • 267
DaveDev
  • 41,155
  • 72
  • 223
  • 385
  • 8
    Are you trying to do URL-encoding of a string? If so, it's better to ask for help with that than just how to handle the spaces. – Lasse V. Karlsen Sep 25 '10 at 18:16
  • 2
    @Lasse, I suppose ultimately that is what I'm trying to do as the string that I want to format will eventually become part of a URL. However, I think the question still stands on its own merrit, as replacing all occurrences of a sub-string inside a string isn't immediately obvious. – DaveDev Sep 25 '10 at 20:13
  • 15
    Right, that was my suspicion too. The answer to that one is: use `encodeURIComponent()`. Don't try to hack it yourself with string replace; it's a lot trickier than you think. This will encode spaces to `%20` rather than `+` though. `%20` is just as valid (in fact more valid, as it works in path components, whereas `+` only means a space in query components), but if you want it to look marginally prettier you can always do a `replace(/%20/g, '+')` afterwards of course. You might be tempted to use `escape()` because it does use `+`, but it also gets all non-ASCII characters wrong—avoid. – bobince Sep 26 '10 at 00:39
  • 1
    I'll agree with that, the question has merit on its own :) I just wanted to know if that's where you were trying to end up, there might be better solutions for you. But yes, the question is good on its own, no doubt about that. I know enough javascript to scrape by, and that .replace didn't replace all the occurances was news to me. – Lasse V. Karlsen Sep 26 '10 at 06:55
  • 3
    Comparison of regex and split/join on tiny and longer strings. http://jsperf.com/replace-characters-in-string – iabw Jul 20 '12 at 18:48
  • You waited 4 years to spring this? – DaveDev Nov 24 '14 at 14:52
  • 1
    The answer of @Andrew below is the most right one, `str.replace(/\s+/g, '+')` because in case your string contrains chaining whitespaces, it will also replace chaning whiteplaces with one replacement, e.g. `a----b--c-d` will be `a+b+c+d`. It makes more sense. Isn't it? – O Connor Jan 21 '20 at 16:04
  • In the latest versions of most popular browsers, you can use replaceAll as shown here: `let result = "a b c".replaceAll(" ", "+");` `// result is "a+b+c"` – Sunny Sultan Jan 17 '21 at 10:20

9 Answers9

612

You need the /g (global) option, like this:

var replaced = str.replace(/ /g, '+');

You can give it a try here. Unlike most other languages, JavaScript, by default, only replaces the first occurrence.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
599

Here's an alternative that doesn't require regex:

var str = 'a b c';
var replaced = str.split(' ').join('+');
Dagg Nabbit
  • 75,346
  • 19
  • 113
  • 141
  • 31
    This selected solution is slower on large replacement compared to the reg expression version. Test with the 3 solutions posted: http://jsbin.com/isadi3/2 Firefox has minimal timing difference, IE has a noticeable difference. So if speed matters and you have a large set of replacements, reg exp is the way to go. – epascarello Sep 30 '10 at 04:27
  • 51
    use str = str.replace(/\s/g, "+"); – Jitendra Pancholi Jul 16 '14 at 09:46
  • 4
    @JitendraPancholi that replaces all whitespace, not just the space character. The other regex answer here is fine. – Dagg Nabbit Jul 16 '14 at 10:23
  • @DaggNabbit: As per the question, he wants to replace white spaces with + symbol, even your solution is doing the same. – Jitendra Pancholi Jul 16 '14 at 10:45
  • 2
    @JitendraPancholi he wants to replace *spaces*, not "white spaces." In this context I assume by *spaces* he means only the space character, not just any old whitespace like `/s` would match. Particularly because he is doing this in JavaScript, and replacing the space character (but not other whitespace) with the `+` character is a standard way to encode URLs. This is probably why the regex solution that only replaces space characters has 10x the votes of the one that replaces all whitespace. – Dagg Nabbit Jul 16 '14 at 10:52
  • Using a split and join is an overhead if we have large data. So its always good to opt a regular expression for the same if possible. http://jsfiddle.net/aC5ZW/ – Jitendra Pancholi Jul 16 '14 at 10:56
  • http://jsfiddle.net/aC5ZW/3/ having a tab, line feed or form feed in the string, my solution works for all. – Jitendra Pancholi Jul 16 '14 at 10:59
  • re: overhead: see the last comment on the question. It's significantly less overhead in some browsers for a small amount of data, which is probably what he's dealing with. In some browsers, it's more. Performance is a moot point here, one goes faster and the other goes slower as browsers make tweaks between versions – Dagg Nabbit Jul 16 '14 at 11:01
  • re: tabs: you're missing my point. If he's doing what it looks like he's doing, he's not going to *want* it to convert all those characters to `+`. He's only going to want to convert the space character. – Dagg Nabbit Jul 16 '14 at 11:02
  • I got your point and also had a look to the comparison, and if we have even 30 replacement, spit/join was apx 90% slower than regex, with 2 replacements, it was only 23% slower. – Jitendra Pancholi Jul 16 '14 at 11:05
  • It's most likely a URL. You're not going to have 30 spaces in a URL. – Dagg Nabbit Jul 16 '14 at 11:06
  • And instead of \s, If i change it to ' ', my solution would still better. – Jitendra Pancholi Jul 16 '14 at 11:06
  • Yes, a regex solution with a literal space character would probably be better. This answer was meant as an alternative for people who didn't want to use regex. That's why it begins with "Here's an alternative." I can't help that the OP accepted it. – Dagg Nabbit Jul 16 '14 at 11:07
  • Yes, it is mentioned in comments below the question, url may have that replacements, Even i worked on a project which had the same requirement. I had around 30+ replacement in the url. – Jitendra Pancholi Jul 16 '14 at 11:08
  • 1
    If your projects are using URLs with 30 spaces in them, you have bigger things to worry about than microptimizing string replacements. – Dagg Nabbit Jul 16 '14 at 11:09
  • @DaggNabbit: See the last comment in my solution. :D – Jitendra Pancholi May 15 '15 at 11:15
  • Split() and Join() are way overpowered and unnecessary here, when a regex is infinitely more efficient. – HoldOffHunger Sep 19 '17 at 19:33
  • I use a version inspired by the trim polyfill str = str.replace(/[\s\uFEFF\xA0]/g, "+"); ... IE "yeeay" – stefan Mar 23 '18 at 11:32
  • https://stackoverflow.com/a/3794936/4429637 this is the best solution. – Lasitha Lakmal Aug 03 '19 at 21:15
130
var str = 'a b c';
var replaced = str.replace(/\s/g, '+');
epascarello
  • 204,599
  • 20
  • 195
  • 236
104

You can also do it like:

str = str.replace(/\s/g, "+");

Have a look at this fiddle.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Jitendra Pancholi
  • 7,897
  • 12
  • 51
  • 84
  • Could you please add explanation to why this is good solution to the problem. – Matas Vaitkevicius Jul 16 '14 at 10:47
  • 1
    Wasn't my downvote, I got a review task to check due to length of content. I assume someone more demanding didn't see explanation and downvoted without bothering to comment. Please put your comment into answer. – Matas Vaitkevicius Jul 16 '14 at 10:53
  • Ok, i have added fiddle in my answer. – Jitendra Pancholi Jul 16 '14 at 10:55
  • 13
    Another possible reason for downvote is that this answer was [already posted](http://stackoverflow.com/a/3795130/451518) almost four years ago – default locale Jul 25 '14 at 13:25
  • 2
    @Jitendra Pancholi Thank you very much, you answer did help me, cuz I had some Japanese :) spaces, that I won't be able to replace by .split(' ').join('+'); Your answer did help me. Thanks man. – whitesiroi May 15 '15 at 10:48
34

Use global search in the string. g flag

str.replace(/\s+/g, '+');

source: replaceAll function

Andrew
  • 483
  • 5
  • 3
  • 1
    I have tested many regex above your answer, but your answer is the most right, because it also replaces multiple chainning white spaces. – O Connor Jan 21 '20 at 15:57
  • 4
    Does not work: [Demo](https://jsbin.com/kocufiteva/edit?html,js,console,output) Input: `"hello !!!"`, expected output: `"hello++++!!!"`, actual output: `"hello+!!!"` – HoldOffHunger Jul 31 '20 at 17:41
32

Use a regular expression with the g modifier:

var replaced = str.replace(/ /g, '+');

From Using Regular Expressions with JavaScript and ActionScript:

/g enables "global" matching. When using the replace() method, specify this modifier to replace all matches, rather than only the first one.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
16

You need to look for some replaceAll option

str = str.replace(/ /g, "+");

this is a regular expression way of doing a replaceAll.

function ReplaceAll(Source, stringToFind, stringToReplace) {
    var temp = Source;
    var index = temp.indexOf(stringToFind);

    while (index != -1) {
        temp = temp.replace(stringToFind, stringToReplace);
        index = temp.indexOf(stringToFind);
    }

    return temp;
}

String.prototype.ReplaceAll = function (stringToFind, stringToReplace) {
    var temp = this;
    var index = temp.indexOf(stringToFind);

    while (index != -1) {
        temp = temp.replace(stringToFind, stringToReplace);
        index = temp.indexOf(stringToFind);
    }

    return temp;

};
mustafa.0x
  • 1,476
  • 2
  • 17
  • 30
sushil bharwani
  • 29,685
  • 30
  • 94
  • 128
7

NON BREAKING SPACE ISSUE

In some browsers

(MSIE "as usually" ;-))

replacing space in string ignores the non-breaking space (the 160 char code).

One should always replace like this:

myString.replace(/[ \u00A0]/, myReplaceString)

Very nice detailed explanation:

http://www.adamkoch.com/2009/07/25/white-space-and-character-160/

Community
  • 1
  • 1
Motlicek Petr
  • 767
  • 9
  • 10
-3

Do this recursively:

public String replaceSpace(String s){
    if (s.length() < 2) {
        if(s.equals(" "))
            return "+";
        else
            return s;
    }
    if (s.charAt(0) == ' ')
        return "+" + replaceSpace(s.substring(1));
    else
        return s.substring(0, 1) + replaceSpace(s.substring(1));
}
Kijewski
  • 25,517
  • 12
  • 101
  • 143
Rick
  • 3
  • 1