2

I need to wrap the two last characters in a string in a separate <span>:

-1:23 // This is what I have
-1:<span>2</span><span>3</span> // This is what I want

The following matches the last character – but how can I make it match the second last as well?

str.replace(/(.$)/, "<span>$1</span>");

Thanks :)

Tonald Drump
  • 1,227
  • 1
  • 19
  • 32

2 Answers2

3

You may use

.replace(/.(?=.?$)/g, "<span>$&</span>")

See the regex demo

If these must be digits, replace . with \d:

.replace(/\d(?=\d?$)/g, "<span>$&</span>")

The pattern matches

  • \d - a digit
  • (?=\d?$) - that is followed with an end of string or a digit and end of string.

The $& is a replacement backreference that references the whole match value from the string replacement pattern.

JS demo:

console.log("-1:23".replace(/.(?=.?$)/g, "<span>$&</span>"));
console.log("-1:23".replace(/\d(?=\d?$)/g, "<span>$&</span>"));

Now, to make it more dynamic, you may use a limiting (range/interval) quantifier:

function wrap_chars(text, num_chars) {
  var reg = new RegExp(".(?=.{0," + (num_chars-1) + "}$)", "g");
  return text.replace(reg, "<span>$&</span>");
}
console.log(wrap_chars("-1:23", 1)); // wrap one char at the end with span
console.log(wrap_chars("-1:23", 2)); // wrap two chars at the end with span
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Why not use explicit quantifiers? `.{2}$` should achieve the same effect, right? – Vogel612 Jul 08 '18 at 10:19
  • @Vogel612 The `.{2}$` pattern will yield [`-1:23`](https://regex101.com/r/c29u0q/2). That was my first thought, that is why I closed the question. When I realized it is not the case, I reopened. I also added a dynamoc solution to wrap N chars at the end of the string. – Wiktor Stribiżew Jul 08 '18 at 16:13
1

You can add another group before the last one, which also matches a single character ((.)), then wrap each of them using references ($1 and $2):

var str = '-1:23'.replace(/(.)(.)$/, '<span>$1</span><span>$2</span>')
console.log(str);
juzraai
  • 5,693
  • 8
  • 33
  • 47