-2

I need to implement a method in Javascript adding whitespaces around / with no surrounding whitespaces.

Example: hello/this /is a/ complicated/task should result in hello / this /is a/ complicated / task

M approach so far:

inputString.replace(new RegExp(/([^\s])\/([^\s])/), '$1 / $2');

But this replaces only the first occurance. How does one make it replace all?

Phil
  • 7,065
  • 8
  • 49
  • 91

2 Answers2

2

You're missing the global flag in the RegExp.

Change /([^\s])\/([^\s])/ to /([^\s])\/([^\s])/g

More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp

Edit

You could also do it like this: new RegExp(/([^\s])\/([^\s])/, 'g')

Baruch
  • 2,381
  • 1
  • 17
  • 29
1

The regular expression you are using only matches occurrences of / if a space is not present at both sides. So some text/ some more does not match because there is already a space to the right of the /.

Instead, you could assert the following with your replace function:

  1. Find all / characters (/g modifier, for global)
  2. If a space occurs before a particular /, match it as well (use ? for optional)
  3. If a space occurs after a particular /, match it as well (use ? for optional)
  4. replace all matches with a literal / surrounded with space characters

That would give you the following statement:

inputString.replace(/\s?\/\s?/g, ' / ');

This will give you: 'hello / this / is a / complicated / task'.

Your preferred output suggests that no spaces should surround multi-word sequences. We can accomplish this the easiest by chaining another replace call, rather than trying to fit all this in one single regular expression. The thing we are now trying to match is multi-word sequences (2 or more words separated by spaces, surrounded by spaces), and capture only the multiword sequences without the surrounding spaces:

  1. Find a substring that starts and ends with an optional space:
    \s?\s?

  2. Capture everything in between those spaces:
    \s?()\s?

  3. The captured string should start with a word-character sequence:
    \s?(\w+)\s?

  4. Ensure that the regex does not match single-word sequences, by adding a non-capturing group inside the capture group, that matches at least once (+) a substring that starts with a space, and then another word sequence:
    \s?(\w+(?:\s\w+)+)\s?

Now we can write the following chain:

inputString
    .replace(/\s?\/\s?/g, ' / ')
    .replace(/\s?(\w+(?:\s\w+)+)\s?/g, '$1');

If you want to ensure no leading or trailing spaces occur in your result, and the possibility exists that inputString starts and/or ends with a /, you can chain a String.prototype.trim call after the replace() calls:

inputString
    .replace(/\s?\/\s?/g, ' / ')
    .replace(/\s?(\w+(?:\s\w+)+)\s?/g, '$1')
    .trim();
JJWesterkamp
  • 7,559
  • 1
  • 22
  • 28