Javascript regex, replace all characters other than numbers - javascript

I would like to replace all the characters other than 0-9 in a string, using Javascript.
Why would this regex not work ?
"a100.dfwe".replace(/([^0-9])+/i, "")

You need the /g modifier to replace every occurrence:
"a100.dfwe".replace(/[^0-9]+/g, "");
I also removed the redundant i modifier and the unused capturing sub-expression braces for you. As others have pointed out, you can also use \D to shorten it even further:
"a100.dfwe".replace(/\D+/g, "");

\D means “not digit”:
"a100.dfwe".replace(/\D/g, "")

What about negative numbers:
Using Andy E's example works unless you have a negative number. Then it removes the '-' symbol also leaving you with an always positive number (which might be ok). However if you want to keep number less than 0 I would suggest the following:
"a-100.dfwe".replace(/(?!-)[^0-9.]/g, "") //equals -100
But be careful, because this will leave all '-' symbols, giving you an error if your text looks like "-a-100.dfwe"

It doesn't work because the character class [^0-9] (= anything but digits) with the repetition modifier + will only match one sequence of non-numeric characters, such as "aaa".
For your purpose, use the /g modifier as the others suggest (to replace all matches globally), and you could also use the pre-defined character class \D (= not a digit) instead of [^0-9], which would result in the more concise regex /\D+/.

"string#! 134".replace(/[^a-z^0-9]+/g, " ");
this would return "string 134"

Based off of #user3324764's answer - Make a prototype function and convert the number to a number.
String.prototype.extractNumber = function ()
{
return Number(this.replace(/(?!-)[^0-9.]/g, ""));
};
Example:
"123.456px".extractNumber(); // 123.456

Related

Regex replace not removing characters properly

I have the regular expression:
const regex = /^\d*\.?\d{0,2}$/
and its inverse (I believe) of
const inverse = /^(?!\d*\.?\d{0,2}$)/
The first regex is validating the string fits any positive number, allowing a decimal and two decimal digits (e.g. 150, 14., 7.4, 12.68). The second regex is the inverse of the first, and doing some testing I'm fairly confident it's giving the expected result, as it only validates when the string is anything but a number that may have a decimal and two digits after (e.g. 12..05, a5, 54.357).
My goal is to remove any characters from the string that do not fit the first regex. I thought I could do that this way:
let myString = '123M.45';
let fixed = myString.replace(inverse, '');
But this does not work as intended. To debug, I tried having the replace character changed to something I would be able to see:
let fixed = myString.replace(inverse, 'ZZZ');
When I do this, fixed becomes: ZZZ123M.45
Any help would be greatly appreciated.
I think I understand your logic here trying to find a regex that is the inverse of the regex that matches your valid string, in the hopes that it will allow you to remove any characters that make your string invalid and leave only the valid string. However, I don't think replace() will allow you to solve your problem in this way. From the MDN docs:
The replace() method returns a new string with some or all matches of a pattern replaced by a replacement.
In your inverse pattern you are using a negative lookahead. If we take a simple example of X(?!Y) we can think of this as "match X if not followed by Y". In your pattern your "X" is ^ and your "Y" is \d*\.?\d{0,2}$. From my understanding, the reason you are getting ZZZ123M.45 is that it is finding the first ^ (i.e, the start of the string) that is not followed by your pattern \d*\.?\d{0,2}$, and since 123M.45 doesn't match your "Y" pattern, your negative lookahead is satisfied and the beginning of your string is matched and "replaced" with ZZZ.
That (I think) is an explanation of what you are seeing.
I would propose an alternative solution to your problem that better fits with how I understand the .replace() method. Instead of your inverse pattern, try this one:
const invalidChars = /[^\d\.]|\.(?=\.)|(?<=\.\d\d)\d*/g
const myString = '123M..456444';
const fixed = myString.replace(invalidChars, '');
Here I am using a pattern that I think will match the individual characters that you want to remove. Let's break down what this one is doing:
[^\d\.]: match characters that are not digits
\.(?=\.): match . character if it is followed by another . character.
(?<=\.\d\d)\d*: match digits that are preceded by a decimal and 2 digits
Then I join all these with ORs (|) so it will match any one of the above patterns, and I use the g flag so that it will replace all the matches, not just the first one.
I am not sure if this will cover all your use cases, but I thought I would give it a shot. Here's a link to a breakdown that might be more helpful than mine, and you can use this tool to tweak the pattern if necessary.
I don't think you can do this
remove any characters from the string that do not fit the first regex
Because regex matching is meant for the entire string, and replace is used to replace just a PART inside that string. So the Regex inside replace must be a Regex to match unwanted characters only, not inverted Regex.
What you could do is to validate the string with your original regex, then if it's not valid, replace and validate again.
//if (notValid), replace unwanted character
// replace everything that's not a dot or digit
const replaceRegex = /[^\d.]/g; // notice g flag here to match every occurrence
const myString = '123M.45';
const fixed = myString.replace(replaceRegex, '');
console.log(fixed)
// validate again

Regular expression for check number and +

Sorry for very useless question!
I need regular expression for check this type of string
+7
i was try .replace(/^+[0-9][^\d]/g, '') but it give me all another type of math symbols, i need
First symbol +
Second one number 1 - 9
your regex needs to be
^\+[0-9][^\d]
if you want to match all numbers starting with + you can use
/\+\d+/g
Note this would match +73ab and return +73
If you want just numbers you can use
/\b\+\d+\b/g
Plus + is a special character used in regular expressions to indicate one or more occurrences of the expression before it. That's why it does not work in your example. You should escape it with \.
If you want to get all numbers prefixed by plus in multiline text, you can use:
/\+\d+/gm
For Example:
var numbers = 'skdlfjlk +7fsd \r\nsd;flk+123'.match(/\+\d+/gm);
console.log(numbers); // => ["+7", "+123"]
If by "number" you actually meaning digit from 1 to 9, and you are interested only in first occurrence in the string, you can use:
/\+[1-9]/m
If, in addition, you need it to be the beginning of the string, you can use just:
/^\+[1-9]/

Right way to remove a leading character

Im pretty new to regex and am trying to remove a leading underscore '_' from any string.
replace(/^[_]+/, "")
This works, but I want to be sure: Is this the correct way to do it?
As I can't find a lot about this special problem around the web, I'm asking about it here.
This should be enough:
replace(/^_/, '');
That works however, it will remove 1-n number of leading underscores. For example, _x becomes x but __x becomes x as well; all the way to n number of leading underscores. If you only want to remove the first leading underscore use the following:
some_string.replace(/^_{1}/, '');
This is using a quantifier to match only 1. Note that this quantifier is not greedy, + quantifier is one or more and greedy. You could also use your original code with the non-greedy modifier ? as follows:
some_string.replace(/^[_]+?/, '');
One last note, you don't need to use the character class operator, [...], in this case. It's not wrong or bad form, just unnecessary.

what is max length of string to test regular expression in javascript

I am using following regex if I pass lenghty string to check, regex101.com showing timeout message. Is there any ideal length to test regular expresssion?
^(\d+[\s\r\n\t,]*){1,100}$
https://regex101.com/r/eC5qO7/1
I suggest running a split, then making sure what is split is a number, so:
var test = "123,456 789 101112 asdf";
var numbers = test.split(/\s*,\s*|\s+/);
numbers.forEach(function(n) {
if (n % 1 !== 0) {
alert(n + " is not an integer");
}
});
The catastrophic backtracking is caused by the fact that the [\s\r\n\t,] character class has a * quantifier applied to it, and then a + quantifier is set to the whole group. The regex backtracks into each digit to search for optional whitespace and commas, which creates a huge number of possibilities that the engine tries before running into the "catastrophe".
Besides, there is another potential bottleneck: \s in the character class can also match \r, \n and \t. See see Do character classes present the same risk?.
Without atomic groups and possessive quantifiers, the regex optimization is only possible by means of making one of the "separators" obligatory. In this case, it is clearly a comma (judging by the example string). Since you just want to validate the number of input numbers separated with commas and optional spaces, you can use a simpler regex:
^(?:[0-9]+\s*,\s*){1,100}$
Here, it fails gracefully, and here it matches the string OK.
If a comma at the end is optional, use
^(?:\d+\s*,\s*){1,99}\d+,?\s*$
See demo
Also note you do not need the i modifier, as there are no letters in the pattern.

Allow only a single point in decimal numbers

How can I modify this regular expression to allow numbers with just one point?
/[^0-9\.]/g
It currently allows:
0
0.13
0.13.1 (this should not be allowable)
Your regex doesn't matches what you say it matches. You have used negation in character class, and that too without any quantifier. Currently it would match any non-digit character other than ..
For your requirement, you can use this regex:
/^\d+(\.\d+)?$/
Make the match a positive one:
/^\d*(\.\d+)?$/
Any number of digits, optionally followed by a point and at least one digit. But it’s not worth it to keep a negative match.
If you want to disallow an empty string (which the original regular expression wouldn’t do), you could do this:
/^(?=.)\d*(\.\d+)?$/
But you could also just check for an empty string, which looks better anyways.
I guess this should do /^(\d*)\.{0,1}(\d){0,1}$/ OR /^(\d*)\.?(\d){0,1}$/
(\d*) Represents number of digits before decimal.
\. followed by {0,1} OR ? will make sure that there is only one dot.
(\d){0,1} Allows only one digit after decimal.
You can try the following regex ^[-+]?\d*.?\d*$
Try,
(value.match(/^\d+([.]\d{0,1})?$/))
Try the following:
/^(\d*)(\.\d*)?$/g

Categories