3

It's easy to replace spaces with (say) underscores:

y = x.replace(/ /g, '_');

It's also easy to remove leading spaces:

y = x.replace(/^ +/, '');

But is there a good way to replace only the initial spaces with underscores?

2

3 Answers 3

3

T.J. Crowder's answer is definitely better than this method, but I thought I would add it because it's only a matter of time until lookbehinds are supported in all major browsers. At the time of writing this answer, the V8 engine shipped in Chrome 62 and XS (January 17, 2018 update) are the only implementations of variable length lookbehinds in JavaScript as per EMCA TC39's regexp lookbehind proposal.

Note the regex below contains a trailing space. If you have Chrome 62+ (or if you're in the future; another browser that supports variable length lookbehinds) you can test the regex here.

(?<=^ *) 

const regex = /(?<=^ *) /g
const str = '        something is here'

console.log(str.replace(regex, '_'))

Sign up to request clarification or add additional context in comments.

2 Comments

"T.J. Crowder's answer is definitely better than this method..." I beg to differ. :-) Seriously cool. And since look-behinds are Stage 4, that means they're in at least two implementations (probably V8 and SpiderMonkey) and they'll be in the ES2018 snapshot spec.
@T.J.Crowder it's cool, but doesn't work on all browsers yet. Writing production code I'd still use your method :)
1

I want to replace each of the leading spaces with an underscore

To do that with just one replace call within the current spec,* you'd need the function call version of replace to do that, creating a string of underscores as long as the matched sequence of spaces:

y = x.replace(/^ +/, function(m) {
    return "_".repeat(m.length);
});

or with an ES2015+ arrow function:

y = x.replace(/^ +/, m => "_".repeat(m.length));

Live Example:

const x = "    four spaces";
const y = x.replace(/^ +/, m => "_".repeat(m.length));
console.log(y);

String.prototype.repeat was added in ES2015. If you need to support obsolete JavaScript engines, the MDN page has a polyfill you can use.


* But see ctwheels' answer using a feature from ES2018: Look-behinds. V. clever!

1 Comment

Neat, I haven't really used the fat arrow yet.
1

There's nothing wrong with combining your two regexes together:

var x = '     hello world';
var y = x.replace(/^ +/, u => u.replace(/ /g,  "_"));
console.log(y); // Outputs: ____hello world

A long hand version of the above would be:

var y = x.replace(/^ +/, function (u) { return u.replace(/ /g, "_"));

Essentially the outer regex/replace gets the initial spaces, the inner regex/replace replaces only those spaces with underscores.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.