Jono Freeman
Jono Freeman

Reputation: 11

Regex to target last two spaces in a string

Regex newbie here. I'm trying to write an expression that matches the last two (or n) separate spaces.

       v v
This is a test

I have an ultra simple expression that returns the last space: / (?=[^ ]*$)/i but cannot seem to figure out how to get it to return twice and only twice (or n times)

Upvotes: 1

Views: 268

Answers (2)

The fourth bird
The fourth bird

Reputation: 163277

You might also match a space and assert using a positive lookahead that there is an optional space to the right.

Denoted the space between square brackets just for clarity.

[ ](?=(?:\S+ ){0,1}\S+$)
  • [ ] Match a space
  • (?= Positive lookahead, assert that on the right it
    • (?:\S+ ){0,1} Match 0 or 1 non whitespace chars followed by a space
    • \S+ Match 1+ non whitespace chars
    • $ End of string
  • ) Close lookahead

Regex demo

In the pattern, the quantifier {0,1} lets you specify the amount of spaces to match.

Using {0,2} will match the last 3 spaces, and using {0} will match only the last space.

If there can also be optional spaces at the end:

[ ](?=(?:\S+ ){0,1}\S+ *$)

Regex demo

Upvotes: 0

trincot
trincot

Reputation: 350167

You could use a negative lookahead that will require that there are not two spaces somewhere after the candidate space:

let s = "This is a test";

let result = s.replace(/ (?!.* .* )/gs, "°");

console.log(result);

I must say that this has a bad time complexity. For large strings you will get better performance with lastIndexOf:

let s = "This is a test";

s = "  " + s; // Add dummies to avoid boundary cases
let last = s.lastIndexOf(" ");
let prev = s.lastIndexOf(" ", last - 1);

// Replace those spaces:
let result = s.slice(0, prev) + "°" + s.slice(prev+1, last) + "°" + s.slice(last+1);
// Remove the dummies:
result = result.slice(2);

console.log(result);

Upvotes: 1

Related Questions