You mentioned handling spaces. Here's a solution that handles spaces and potential decimal points in percent:
s = s.replace(/( ?)\d+(?:\.\d+)?%( ?)/g, function(m, c0, c1) { if (c0 === " " && c1 === " ") { return " "; } return ""; });
Live demo: Run | Edit
Here's how it works:
- The initial
( ?)
Is a capture group that captures the space in front of the numbers, if any. If it is not there, it will not work, because ?
makes space optional. \d+
matches leading digits.(?:\.\d+)
matches an optional decimal point followed by additional digits. (This is not a capture group; the format (?:xxx)
is for grouping without capture ?
After it makes everything optional.)%
, of course, corresponds to %
.( ?)
at the end, it captures the space following %
, if any; again optional.String#replace
allows you to call the function to be called, and not just a simple replacement string.- The function gets a complete match as the first argument, and then the capture group as the remaining arguments. If both capture groups have spaces in them, there are spaces on both sides of the percentage field, so we return one space (to avoid jamming the words before and after the percentage together). Otherwise, there was no place before or after the percentage, so we do not return anything, therefore we eat the space that was there.
If you also want to handle things like .25%
, the regex will change a bit:
/( ?)(?:(?:\d+\.\d+)|(?:\.\d+)|(?:\d+))%( ?)/g
Live demo: Run | Edit
Structure:
( ?)
- Same as before.(?:...|...|...)
- alternation, it will correspond to one of the given alternatives. The alternatives we provide are:(?:\d+\.\d+)
is one or more digits, followed by a decimal point, followed by one or more digits.(?:\.\d+)
is the leading decimal point followed by one or more digits(?:\d+)
- Only a series of numbers
%
- match %
( ?)
- Same as before
Everything else is the same.
source share