1

I have a string which looks like below

Your statistics:
The trend is going up.
The most recent value for x*y on 2018-12-09 is 469.44.
The max was 2896 on 2018-12-08 and min was 23.1 on 2018-12-08.
Additionally, the median is 367.95 and the mode is 23.1.
There is higher margin for error/mistake.

As you can see I got some float and int in the string. I need to replace all those occurences with span tag surrounding those occurrences

Here I managed to do something basic like replacing the instances of float and int with XXX. But the problem is there are occurrences of date too and that screws up the operation. So this is what I do:

var string = "Your statistics:<br>The trend is going up.<br>The most recent value for x*y on  2018-12-09 is 469.44.<br>The max was 2896 on 2018-12-08 and  min was 23.1 on 2018-12-08.<br>Additionally, the median is 367.95 and the mode is 23.1.<br>There is higher margin for error/mistake."

string = string.replace(/\d+/g, "XXX");
console.log(string)

This is what I get:

Your statistics:<br>The trend is going up.<br>The most recent value for x*y on  XXX-XXX-XXX is XXX.XXX.<br>The max was XXX on XXX-XXX-XXX and  min was XXX.XXX on XXX-XXX-XXX.<br>Additionally, the median is XXX.XXX and the mode is XXX.XXX.<br>There is higher margin for error/mistake.

Now what I want is replace all occurrences of float and int with a span tag surrounding them something like 469.44 be replaced with <span>469.44</span>, 2896 be replaced with <span>2896<span>

So final string would become something like:

Your statistics:<br>The trend is going up.<br>The most recent value for x*y on  2018-12-09 is <span>469.44</span>.<br>The max was <span>2896</span> on 2018-12-08 and  min was <span>23.1</span> on 2018-12-08.<br>Additionally, the median is <span>367.95</span> and the mode is <span>23.1</span>.<br>There is higher margin for error/mistake.

How do I accomplish this ensuring dates are not messed up?

3 Answers 3

1

This does the job without lookbehind:

var string = "Your statistics:<br>The trend is going up.<br>The most recent value for x*y on  2018-12-09 is -469.44.<br>The max was 2896 on 2018-12-08 and  min was -23.1 on 2018-12-08.<br>Additionally, the median is 367.95 and the mode is 23.1.<br>There is higher margin for error/mistake."

string = string.replace(/(\s)(-?\d+(?:\.\d+)?)([.\s])/g, "$1<span>$2</span>$3");
console.log(string)

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

4 Comments

I'm so glad we have SO so we don't have to actually the horrors of regex
@SouvikRay: De rien ;), glad it helps.
@Toto Hi friend! I needed a small help. Is there any way negative numbers can be covered too? Like -124.33, -21, -0.22 etc. So I want both the minus and the number to be covered. You may post an edit to your answer with your modified regex.
@SouvikRay: Just add -? before the first \d+, see my edit
1

Another solution without lookbehind.

var string = "Your statistics:<br>The trend is going up.<br>The most recent value for x*y on  2018-12-09 is 469.44.<br>The max was 2896 on 2018-12-08 and  min was 23.1 on 2018-12-08.<br>Additionally, the median is 367.95 and the mode is 23.1.<br>There is higher margin for error/mistake."

let newStr = string.replace(/(\d+[^-]\d+|\s\d\s)(?=[^-0-9])/g,str=>`<span>${str}</span>`)
console.log(newStr)

5 Comments

This will not work for numbers that contain only 1 digit.
A serial downvoter was in action, all answers get downvoted! But there is another problem with your regex, it change blah 12 34 blah into blah <span>12 34</span> blah instead of blah <span>12</span> <span>34</span> blah
Thanks for the feedback. Anyway I didn't down vote anything. I am here to learn from others and help others. Not to compete with anyone. I don't know how I can prove that, but I know I didn't down vote anything :) . Thanks a lot again for the feedback!
Forgetting what you just said and back to discussion. This problem doesn't has two consecutive numbers. So I think this should be still valid.
Don't worry, I'm sure it wasn't you that downvoted. Sometimes people downvote without explanations.
0

/(?<!-\d*)\d+(\.\d+)?(?!\d*-)/g

(?<!something) — negative lookbehind. We don't need to capture the numbers, which have -\d* behind.
   • \d — digit, matches any digit from 0 to 9.
   • * — zero or multiple times

\d+(\.\d+)?\d+ any digit from 1 to multiple times (int numers),
   • (\.\d+)\. dot symbol, \d+ any digits (float numbers),
   • ? — "lazy" match, means "zero or one match"

(?!\d*-) — negative lookahead. We don't need digit with - as well.

let bubu = document.getElementById('bubu');

bubu.innerHTML = bubu.innerHTML
  .replace(/(?<!-\d*)\d+(\.\d+)?(?!\d*-)/g, match => '<span class="red">' + match + '</span>')
.red { color: red; }
<p id="bubu">Your statistics:
The trend is going up.
The most recent value for x*y on 2018-12-09 is 469.44.
The max was 2896 on 2018-12-08 and min was 23.1 on 2018-12-08.
Additionally, the median is 367.95 and the mode is 23.1.
There is higher margin for error/mistake.</p>

2 Comments

hey do you want to recheck your solution? The code snippet doesn't run and when I try to run it locally in my system, I get this error 'Invalid regular expression: invalid group specifier name.
caniuse.com/#search=lookbehind - it works, but has pure browser support. Now trying to find old version of lookbehind) stackoverflow.com/questions/641407/… maybe...

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.