Remove spaces from a string from the second occurrence

Asked

Viewed 816 times

7

Currently I am removing spaces using a simple replace() and adding a space I must preserve between the third and fourth character using substr()

let str = 'abc defghijk lmnop qrstuv wx y z'

str = str.replace(/\s+/g, '')
// resultado: 'abcdefghijklmnopqrstuvwxyz'

str = str.substr(0, 3) + ' ' + str.substr(3, str.length)

console.log(str)

What is the most succinct way to achieve the same result using only the method replace()?


PS: I really have little knowledge about the use of RegExp

  • You want to go back to string like it was?

  • No, I want to remove all bad spaces by preserving the first

3 answers

8

Using only replace can also be done, although it probably does not compensate for performance/readability/support.

You can use the following regex:

(?<=\s.*)\s+

Explanation:

(?<=   - Positive lookbehind, que tenha algo atrás
\s+.*) - Que tenha espaço seguido de qualquer coisa
\s+    - O espaço a ser capturado

See this regex in regex101

So you can read this regex as capturing a space that has another space behind followed by anything. For this reason you will not catch the first because it has no back space.

It is worth remembering that this uses Positive lookbehind, which was added to javascript a short time ago and so is likely not to work in older browsers. The second note is that this is a lookbehind of a variable size than most regex Engines of other languages and does not support.

Example:

let str = 'abc defghijk lmnop qrstuv wx y z'

str = str.replace(/(?<=\s+.*)\s+/g, '')

console.log(str)

So I think the best solution is to really do the simple and use a indexOf as suggested to get the first space and replace from there.

  • I liked the answer, much more succinct. A quick test on jsperf.com proved to be faster than using it indexOf(). I am using ES6 syntax and so I use Babel ... I will test using the plugin Babel-plugin-Transform-Modern-regexp and may contribute to the outcome of this response if accepted.

  • @This is interesting. I didn’t test performance, but I would expect it to be slower than the indexOf. I was unaware of this extension of Babel, but if it supports this type of regexes then it turns out to be a good solution.

  • 1

    Currently only the latest versions of Chrome and Node support natively lookbehind, Unfortunately the module cited above for Babel has an untreated ISSUE that is, it is not yet possible to port via Babel..."garimpei bastante" más, it seems that there is no other module that meets this need. No pollyfill either unfortunately. The above mentioned test was using Chrome 68. Thanks again for the good answer.

6

You can capture the position of the first space with the indexOf(), reserve this prefix, and reduce the scope of your replace(), but then the solution is not through regex.

let str = 'abc defghijk lmnop qrstuv wx y z';
let prefix = str.substr(0,str.indexOf(' ')+1);

str = prefix + str.substr(prefix.length).replace(/\s+/g, '');

console.log(str);
//abc defghijklmnopqrstuvwxyz

1

Split + Join

An alternative to keeping the first space is to use Split with the Join.

let str = 'abc defghijk lmnop qrstuv wx y z'

tokens = str.split(' ')

str = tokens[0] + ' ' + tokens.slice(1).join('')

console.log(str)

Explaining the code:

  1. Separates text in an array using the space character as separator.
  2. Take the first text plus 1 space and merge with the rest of the text without the spaces.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.