How to check if value is in preferd format - javascript

i have a input field.
Inside this field the user should only enter text in this format
1+1+2+3
maximum 1+1+1+1+1+1+1+1+1+1+1+1 (12x)
How i can check this
only checking for numbers
var isnum = /^\d+$/.test($(this).val());
will be the half work, but for more i dont know how...

You can use a quantifier to say how many to accept, so:
var isnum = /^\d+(?:\+\d+){0,11}$/.test($(this).val());
That says to accept any number of digits at the beginning, optionally followed by 0 to 11 examples of + and any number of digits.
Live Example:
function test(str, expect) {
var result = /^\d+(?:\+\d+){0,11}$/.test(str);
console.log(str, result, !result === !expect ? "Test:Pass" : "Test:FAIL");
}
test("1", true);
test("1+2+3+4+1234", true);
test("1+1+1+1+1+1+1+1+1+1+1+1", true);
test("1+1+1+1+1+1+1+1+1+1+1+1+1", false);
In a comment you've added:
es only digits and plus-sign and the maximum of entered numbers must be = 12, 6+6 or 3+6+3...
That's a completely different thing, and you can't reasonably test for it with a regular expression (you'd need a ridiculous number of alternatives). Instead, use a regular expression (such as the above) to test the format, then do the sum:
if (/*...the format is good...*/) {
sum = str.split("+").reduce((a, b) => Number(a) + Number(b));
if (sum > 12) {
// disallow it
}
}
Live Example:
function test(str, expect) {
var result = /^\d+(?:\+\d+){0,11}$/.test(str);
if (result) {
result = str.split("+").reduce((a, b) => Number(a) + Number(b)) <= 12;
}
console.log(str, result, !result === !expect ? "Test:Pass" : "Test:FAIL");
}
test("1", true);
test("1+2+3+4+1234", false); // sum > 12
test("1+1+1+1+1+1+1+1+1+1+1+1", true);
test("1+1+1+1+1+1+1+1+1+1+1+1+1", false); // too many
test("12345", false); // sum > 12
In that I've used Number(x) to convert from string to number, but you have a lot of options, which I detail in this answer.

Related

How to get a term before a character?

How to get the number before 'x'?
I tried using .split('x')[0] but it grabs everything before 'x'.
123x // Gives 123
123y+123x - // Gives 123
123x+123x - // Gives 246
I've tested a function which uses regex that I think will work. I've included the results, an explanation of how the function works, and then a commented version of the function.
Note, this doesn't handle any algebra more complex than adding and subtracting simple terms. I would refer to https://newton.now.sh/ for that, it's an API which can handle simplification (I am not affiliated).
Results:
console.log(coefficient("-x+23x")); // 22
console.log(coefficient("123y+123x")); // 123
// replaces spaces
console.log(coefficient("x + 123x")); // 124
console.log(coefficient("-x - 123x")); // -124
console.log(coefficient("1234x-23x")); // 1211
// doesn't account for other letters
console.log(coefficient("-23yx")); // 1
Explanation:
First the function removes spaces. Then it uses a regex, which finds any sequence of numbers that are followed by an 'x'. If there's a +/- in front, the regex keeps that. The function loops through these sequences of numbers, and adds them to a total. If there's an 'x' that does not have numbers with it, its coefficient is assumed as -1 or 1.
Commented Code:
function coefficient(str) {
// remove spaces
str = str.replace(/\s/g, '');
// all powerful regex
var regexp = /(\+|-)?[0-9]*x/g
// total
sum = 0;
// find the occurrences of x
var found = true;
while (found) {
match = regexp.exec(str);
if (match == null) {
found = false;
} else {
// treated as +/- 1 if no proceeding number
if (isNaN(parseInt(match[0]))) {
if (match[0].charAt(0) == "-") {
sum--;
} else {
sum++;
}
// parse the proceeding number
} else {
sum += parseInt(match[0]);
}
}
}
return sum;
}
I don't know if there is sufficient cleverness in ECMAScript regular expressions to do look behind, but you can do it with match and post processing to remove the "x".
If the intention is to sum the terms, then a further operation with reduce is required. Trimming the x could be combined with reduce so that map isn't required.
console.log(
'123x+123x'.match(/\d+x/ig).map(function(v){
return v.slice(0,-1)
}).reduce(function(sum, v){return sum + +v},0)
);
console.log(match('123x+123y+456x', 'x'))
console.log(match('123x+123y+456x', 'y'))
function match(str, x) {
return str.match(new RegExp('\\d+' + x, 'g')).reduce((cur, p) => {
return cur + parseInt(p.substr(0, p.length - x.length))
}, 0)
}

Efficient regex for Canadian postal code function

var regex = /[A-Za-z]\d[A-Za-z] ?\d[A-Za-z]\d/;
var match = regex.exec(value);
if (match){
if ( (value.indexOf("-") !== -1 || value.indexOf(" ") !== -1 ) && value.length() == 7 ) {
return true;
} else if ( (value.indexOf("-") == -1 || value.indexOf(" ") == -1 ) && value.length() == 6 ) {
return true;
}
} else {
return false;
}
The regex looks for the pattern A0A 1B1.
true tests:
A0A 1B1
A0A-1B1
A0A1B1
A0A1B1C << problem child
so I added a check for "-" or " " and then a check for length.
Is there a regex, or more efficient method?
User kind, postal code strict, most efficient format:
/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ -]?\d[ABCEGHJ-NPRSTV-Z]\d$/i
Allows:
h2t-1b8
h2z 1b8
H2Z1B8
Disallows:
Z2T 1B8 (leading Z)
H2T 1O3 (contains O)
Leading Z,W or to contain D, F, I, O, Q or U
Add anchors to your pattern:
var regex = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/;
^ means "start of string" and $ means "end of string". Adding these anchors will prevent the C from slipping in to the match since your pattern will now expect a whole string to consist of 6 (sometimes 7--as a space) characters. This added bonus should now alleviate you of having to subsequently check the string length.
Also, since it appears that you want to allow hyphens, you can slip that into an optional character class that includes the space you were originally using. Be sure to leave the hyphen as either the very first or very last character; otherwise, you will need to escape it (using a leading backslash) to prevent the regex engine from interpreting it as part of a character range (e.g. A-Z).
This one handles us and ca codes.
function postalFilter (postalCode) {
if (! postalCode) {
return null;
}
postalCode = postalCode.toString().trim();
var us = new RegExp("^\\d{5}(-{0,1}\\d{4})?$");
var ca = new RegExp(/([ABCEGHJKLMNPRSTVXY]\d)([ABCEGHJKLMNPRSTVWXYZ]\d){2}/i);
if (us.test(postalCode.toString())) {
return postalCode;
}
if (ca.test(postalCode.toString().replace(/\W+/g, ''))) {
return postalCode;
}
return null;
}
// these 5 return null
console.log(postalFilter('1a1 a1a'));
console.log(postalFilter('F1A AiA'));
console.log(postalFilter('A12345-6789'));
console.log(postalFilter('W1a1a1')); // no "w"
console.log(postalFilter('Z1a1a1')); // ... or "z" allowed in first position!
// these return canada postal less space
console.log(postalFilter('a1a 1a1'));
console.log(postalFilter('H0H 0H0'));
// these return unaltered
console.log(postalFilter('H0H0H0'));
console.log(postalFilter('a1a1a1'));
console.log(postalFilter('12345'));
console.log(postalFilter('12345-6789'));
console.log(postalFilter('123456789'));
// strip spaces
console.log(postalFilter(' 12345 '));
You have a problem with the regex StatsCan has posted the rules for what is a valid Canadian postal code:
The postal code is a six-character code defined and maintained by
Canada Post Corporation (CPC) for the purpose of sorting and
delivering mail. The characters are arranged in the form ‘ANA NAN’,
where ‘A’ represents an alphabetic character and ‘N’ represents a
numeric character (e.g., K1A 0T6). The postal code uses 18 alphabetic
characters and 10 numeric characters. Postal codes do not include the
letters D, F, I, O, Q or U, and the first position also does not make
use of the letters W or Z.
The regex should be if you wanted it strict.
/^[ABCEGHJ-NPRSTVXY][0-9][ABCEGHJ-NPRSTV-Z] [0-9][ABCEGHJ-NPRSTV-Z][0-9]$/
Also \d means number not necessarily 0-9 there may be the one errant browser that treats it as any number in unicode space which would likely cause issues for you downstream.
from: https://trajano.net/2017/05/canadian-postal-code-validation/
This is a function that will do everything for you in one shot. Accepts AAA BBB and AAABBB with or without space.
function go_postal(){
let postal = $("#postal").val();
var regex = /^[A-Za-z]\d[A-Za-z][ -]?\d[A-Za-z]\d$/;
var pr = regex .test(postal);
if(pr === true){
//all good
} else {
// not so much
}
}
function postalFilter (postalCode, type) {
if (!postalCode) {
return null;
}
postalCode = postalCode.toString().trim();
var us = new RegExp("^\\d{5}(-{0,1}\\d{4})?$");
// var ca = new RegExp(/^((?!.*[DFIOQU])[A-VXY][0-9][A-Z])|(?!.*[DFIOQU])[A-VXY][0-9][A-Z]\ ?[0-9][A-Z][0-9]$/i);
var ca = new RegExp(/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ]( )?\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i);
if(type == "us"){
if (us.test(postalCode.toString())) {
console.log(postalCode);
return postalCode;
}
}
if(type == "ca")
{
if (ca.test(postalCode.toString())) {
console.log(postalCode);
return postalCode;
}
}
return null;
}
regex = new RegExp(/^[ABCEGHJ-NPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][-]?\d[ABCEGHJ-NPRSTV-Z]\d$/i);
if(regex.test(value))
return true;
else
return false;
This is a shorter version of the original problem, where value is any text value. Furthermore, there is no need to test for value length.

Convert String with Dot or Comma as decimal separator to number in JavaScript

An input element contains numbers a where comma or dot is used as decimal separator and space may be used to group thousands like this:
'1,2'
'110 000,23'
'100 1.23'
How would one convert them to a float number in the browser using JavaScript?
jQuery and jQuery UI are used. Number(string) returns NaN and parseFloat() stops on first space or comma.
Do a replace first:
parseFloat(str.replace(',','.').replace(' ',''))
I realise I'm late to the party, but I wanted a solution for this that properly handled digit grouping as well as different decimal separators for currencies. As none of these fully covered my use case I wrote my own solution which may be useful to others:
function parsePotentiallyGroupedFloat(stringValue) {
stringValue = stringValue.trim();
var result = stringValue.replace(/[^0-9]/g, '');
if (/[,\.]\d{2}$/.test(stringValue)) {
result = result.replace(/(\d{2})$/, '.$1');
}
return parseFloat(result);
}
This should strip out any non-digits and then check whether there was a decimal point (or comma) followed by two digits and insert the decimal point if needed.
It's worth noting that I aimed this specifically for currency and as such it assumes either no decimal places or exactly two. It's pretty hard to be sure about whether the first potential decimal point encountered is a decimal point or a digit grouping character (e.g., 1.542 could be 1542) unless you know the specifics of the current locale, but it should be easy enough to tailor this to your specific use case by changing \d{2}$ to something that will appropriately match what you expect to be after the decimal point.
The perfect solution
accounting.js is a tiny JavaScript library for number, money and currency formatting.
Check this for ref
You could replace all spaces by an empty string, all comas by dots and then parse it.
var str = "110 000,23";
var num = parseFloat(str.replace(/\s/g, "").replace(",", "."));
console.log(num);
I used a regex in the first one to be able to match all spaces, not just the first one.
This is the best solution
http://numeraljs.com/
numeral().unformat('0.02'); = 0.02
What about:
parseFloat(str.replace(' ', '').replace('.', '').replace(',', '.'));
All the other solutions require you to know the format in advance. I needed to detect(!) the format in every case and this is what I end up with.
function detectFloat(source) {
let float = accounting.unformat(source);
let posComma = source.indexOf(',');
if (posComma > -1) {
let posDot = source.indexOf('.');
if (posDot > -1 && posComma > posDot) {
let germanFloat = accounting.unformat(source, ',');
if (Math.abs(germanFloat) > Math.abs(float)) {
float = germanFloat;
}
} else {
// source = source.replace(/,/g, '.');
float = accounting.unformat(source, ',');
}
}
return float;
}
This was tested with the following cases:
const cases = {
"0": 0,
"10.12": 10.12,
"222.20": 222.20,
"-222.20": -222.20,
"+222,20": 222.20,
"-222,20": -222.20,
"-2.222,20": -2222.20,
"-11.111,20": -11111.20,
};
Suggestions welcome.
Here's a self-sufficient JS function that solves this (and other) problems for most European/US locales (primarily between US/German/Swedish number chunking and formatting ... as in the OP). I think it's an improvement on (and inspired by) Slawa's solution, and has no dependencies.
function realParseFloat(s)
{
s = s.replace(/[^\d,.-]/g, ''); // strip everything except numbers, dots, commas and negative sign
if (navigator.language.substring(0, 2) !== "de" && /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(s)) // if not in German locale and matches #,###.######
{
s = s.replace(/,/g, ''); // strip out commas
return parseFloat(s); // convert to number
}
else if (/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(s)) // either in German locale or not match #,###.###### and now matches #.###,########
{
s = s.replace(/\./g, ''); // strip out dots
s = s.replace(/,/g, '.'); // replace comma with dot
return parseFloat(s);
}
else // try #,###.###### anyway
{
s = s.replace(/,/g, ''); // strip out commas
return parseFloat(s); // convert to number
}
}
Here is my solution that doesn't have any dependencies:
return value
.replace(/[^\d\-.,]/g, "") // Basic sanitization. Allows '-' for negative numbers
.replace(/,/g, ".") // Change all commas to periods
.replace(/\.(?=.*\.)/g, ""); // Remove all periods except the last one
(I left out the conversion to a number - that's probably just a parseFloat call if you don't care about JavaScript's precision problems with floats.)
The code assumes that:
Only commas and periods are used as decimal separators. (I'm not sure if locales exist that use other ones.)
The decimal part of the string does not use any separators.
try this...
var withComma = "23,3";
var withFloat = "23.3";
var compareValue = function(str){
var fixed = parseFloat(str.replace(',','.'))
if(fixed > 0){
console.log(true)
}else{
console.log(false);
}
}
compareValue(withComma);
compareValue(withFloat);
This answer accepts some edge cases that others don't:
Only thousand separator: 1.000.000 => 1000000
Exponentials: 1.000e3 => 1000e3 (1 million)
Run the code snippet to see all the test suite.
const REGEX_UNWANTED_CHARACTERS = /[^\d\-.,]/g
const REGEX_DASHES_EXEPT_BEGINNING = /(?!^)-/g
const REGEX_PERIODS_EXEPT_LAST = /\.(?=.*\.)/g
export function formatNumber(number) {
// Handle exponentials
if ((number.match(/e/g) ?? []).length === 1) {
const numberParts = number.split('e')
return `${formatNumber(numberParts[0])}e${formatNumber(numberParts[1])}`
}
const sanitizedNumber = number
.replace(REGEX_UNWANTED_CHARACTERS, '')
.replace(REGEX_DASHES_EXEPT_BEGINING, '')
// Handle only thousands separator
if (
((sanitizedNumber.match(/,/g) ?? []).length >= 2 && !sanitizedNumber.includes('.')) ||
((sanitizedNumber.match(/\./g) ?? []).length >= 2 && !sanitizedNumber.includes(','))
) {
return sanitizedNumber.replace(/[.,]/g, '')
}
return sanitizedNumber.replace(/,/g, '.').replace(REGEX_PERIODS_EXEPT_LAST, '')
}
function formatNumberToNumber(number) {
return Number(formatNumber(number))
}
const REGEX_UNWANTED_CHARACTERS = /[^\d\-.,]/g
const REGEX_DASHES_EXEPT_BEGINING = /(?!^)-/g
const REGEX_PERIODS_EXEPT_LAST = /\.(?=.*\.)/g
function formatNumber(number) {
if ((number.match(/e/g) ?? []).length === 1) {
const numberParts = number.split('e')
return `${formatNumber(numberParts[0])}e${formatNumber(numberParts[1])}`
}
const sanitizedNumber = number
.replace(REGEX_UNWANTED_CHARACTERS, '')
.replace(REGEX_DASHES_EXEPT_BEGINING, '')
if (
((sanitizedNumber.match(/,/g) ?? []).length >= 2 && !sanitizedNumber.includes('.')) ||
((sanitizedNumber.match(/\./g) ?? []).length >= 2 && !sanitizedNumber.includes(','))
) {
return sanitizedNumber.replace(/[.,]/g, '')
}
return sanitizedNumber.replace(/,/g, '.').replace(REGEX_PERIODS_EXEPT_LAST, '')
}
const testCases = [
'1',
'1.',
'1,',
'1.5',
'1,5',
'1,000.5',
'1.000,5',
'1,000,000.5',
'1.000.000,5',
'1,000,000',
'1.000.000',
'-1',
'-1.',
'-1,',
'-1.5',
'-1,5',
'-1,000.5',
'-1.000,5',
'-1,000,000.5',
'-1.000.000,5',
'-1,000,000',
'-1.000.000',
'1e3',
'1e-3',
'1e',
'-1e',
'1.000e3',
'1,000e-3',
'1.000,5e3',
'1,000.5e-3',
'1.000,5e1.000,5',
'1,000.5e-1,000.5',
'',
'a',
'a1',
'a-1',
'1a',
'-1a',
'1a1',
'1a-1',
'1-',
'-',
'1-1'
]
document.getElementById('tbody').innerHTML = testCases.reduce((total, input) => {
return `${total}<tr><td>${input}</td><td>${formatNumber(input)}</td></tr>`
}, '')
<table>
<thead><tr><th>Input</th><th>Output</th></tr></thead>
<tbody id="tbody"></tbody>
</table>
From number to currency string is easy through Number.prototype.toLocaleString. However the reverse seems to be a common problem. The thousands separator and decimal point may not be obtained in the JS standard.
In this particular question the thousands separator is a white space " " but in many cases it can be a period "." and decimal point can be a comma ",". Such as in 1 000 000,00 or 1.000.000,00. Then this is how i convert it into a proper floating point number.
var price = "1 000.000,99",
value = +price.replace(/(\.|\s)|(\,)/g,(m,p1,p2) => p1 ? "" : ".");
console.log(value);
So the replacer callback takes "1.000.000,00" and converts it into "1000000.00". After that + in the front of the resulting string coerces it into a number.
This function is actually quite handy. For instance if you replace the p1 = "" part with p1 = "," in the callback function, an input of 1.000.000,00 would result 1,000,000.00

textbox validation accepting Ports in javascript

the question was accepting one or many ports that has one space between them with help of friends,
I used this one for my answer but for example if I enter 88888 it will alert me such this thing:
88888NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN is not correct
how can I correct this
<script type="text/javascript">
function portvalidating(field)
{
var output='';
m=field.value;
if(/^\d{1,5}([ ]\d{1,5})*$/.test(m))
{
var parts = m.split(' ');
for(i in parts)
{
var p= parseInt(parts[i]);
if(!((0 <= p) && (p<= 65535) && !isNaN(p)))
{
output+=p;
}
}
if(output=='')
var dummy=1;
else alert(output+'is not correct');
}
else alert('please enter a valid port!');
}
Unfortunately, regular expressions can't handle 'ranges', so you can't do this exactly as you want with regexp (therorically you can, but the regex would be hiper,hiper long).
However, you could validate your space-separated numbers with this regexp:
/^\d{1,5}([ ]\d{1,5})*$/
This will do what you want, except validating the range you supplied. But it controls that numbers have between 1 and 5 digits, and the other things you asked.
Hope this helps. Cheers
A crude regex without much error checking would be: exp = /\d{1,5}/g and then call .match(exp) on your string. However, you will need to use parseInt to convert the output to a number so that you can check it's value against your constraints.
I think you may be able to do this easier without Regex. Some quick code to split and parse a string is:
var s = "21 456 -32 70000";
var parts = s.split(' ');
var output;
for(i in parts)
{
p = parseInt(parts[i]);
if( (0 <= p) && (p <= 65535) && !isNaN(p) )
output += p+"<br />";
}
Hopefully this helps to some degree.
I think you would compromise your performance here if you want you are trying to validate a simple Integer value via RegEx.
IMO, try spiting the string with Space (' ') and and convert each value to Integer and perform myInt < 65535.
for( String str : portNumbers.split(' ') ){
try{
int i = Integer.parseInteger( str );
if( 0 > i && i > 65535 ){
errorMessage = str + " is out of range.";
}
}catch (NumberFormatException e) {
errorMessage = str + " is not a valid port.";
}
}
(6553[0-5]|655[0-2][0-9]|65[0-4][0-9][0-9]|6[0-4][0-9][0-9][0-9]|\d{2,4}|[1-9])

javascript regular expression to check for IP addresses

I have several ip addresses like:
115.42.150.37
115.42.150.38
115.42.150.50
What type of regular expression should I write if I want to search for the all the 3 ip addresses? Eg, if I do 115.42.150.* (I will be able to search for all 3 ip addresses)
What I can do now is something like: /[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}/ but it can't seems to work well.
Thanks.
May be late but, someone could try:
Example of VALID IP address
115.42.150.37
192.168.0.1
110.234.52.124
Example of INVALID IP address
210.110 – must have 4 octets
255 – must have 4 octets
y.y.y.y – only digits are allowed
255.0.0.y – only digits are allowed
666.10.10.20 – octet number must be between [0-255]
4444.11.11.11 – octet number must be between [0-255]
33.3333.33.3 – octet number must be between [0-255]
JavaScript code to validate an IP address
function ValidateIPaddress(ipaddress) {
if (/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress)) {
return (true)
}
alert("You have entered an invalid IP address!")
return (false)
}
Try this one, it's a shorter version:
^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$
Explained:
^ start of string
(?!0) Assume IP cannot start with 0
(?!.*\.$) Make sure string does not end with a dot
(
(
1?\d?\d| A single digit, two digits, or 100-199
25[0-5]| The numbers 250-255
2[0-4]\d The numbers 200-249
)
\.|$ the number must be followed by either a dot or end-of-string - to match the last number
){4} Expect exactly four of these
$ end of string
Unit test for a browser's console:
var rx=/^(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/;
var valid=['1.2.3.4','11.11.11.11','123.123.123.123','255.250.249.0','1.12.123.255','127.0.0.1','1.0.0.0'];
var invalid=['0.1.1.1','01.1.1.1','012.1.1.1','1.2.3.4.','1.2.3\n4','1.2.3.4\n','259.0.0.1','123.','1.2.3.4.5','.1.2.3.4','1,2,3,4','1.2.333.4','1.299.3.4'];
valid.forEach(function(s){if (!rx.test(s))console.log('bad valid: '+s);});
invalid.forEach(function(s){if (rx.test(s)) console.log('bad invalid: '+s);});
If you are using nodejs try:
require('net').isIP('10.0.0.1')
doc net.isIP()
The regex you've got already has several problems:
Firstly, it contains dots. In regex, a dot means "match any character", where you need to match just an actual dot. For this, you need to escape it, so put a back-slash in front of the dots.
Secondly, but you're matching any three digits in each section. This means you'll match any number between 0 and 999, which obviously contains a lot of invalid IP address numbers.
This can be solved by making the number matching more complex; there are other answers on this site which explain how to do that, but frankly it's not worth the effort -- in my opinion, you'd be much better off splitting the string by the dots, and then just validating the four blocks as numeric integer ranges -- ie:
if(block >= 0 && block <= 255) {....}
Hope that helps.
Don't write your own regex or copy paste! You probably won't cover all edge cases (IPv6, but also octal IPs, etc). Use the is-ip package from npm:
var isIp = require('is-ip');
isIp('192.168.0.1');
isIp('1:2:3:4:5:6:7:8');
Will return a Boolean.
Try this one.. Source from here.
"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"
Below Solution doesn't accept Padding Zeros
Here is the cleanest way to validate an IP Address, Let's break it down:
Fact: a valid IP Address is has 4 octets, each octets can be a number between 0 - 255
Breakdown of Regex that matches any value between 0 - 255
25[0-5] matches 250 - 255
2[0-4][0-9] matches 200 - 249
1[0-9][0-9] matches 100 - 199
[1-9][0-9]? matches 1 - 99
0 matches 0
const octet = '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)';
Notes: When using new RegExp you should use \\. instead of \. since string will get escaped twice.
function isValidIP(str) {
const octet = '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)';
const regex = new RegExp(`^${octet}\\.${octet}\\.${octet}\\.${octet}$`);
return regex.test(str);
}
If you want something more readable than regex for ipv4 in modern browsers you can go with
function checkIsIPV4(entry) {
var blocks = entry.split(".");
if(blocks.length === 4) {
return blocks.every(function(block) {
return parseInt(block,10) >=0 && parseInt(block,10) <= 255;
});
}
return false;
}
A short RegEx: ^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$
Example
const isValidIp = value => (/^(?:(?:^|\.)(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)){4}$/.test(value) ? true : false);
// valid
console.log("isValidIp('0.0.0.0') ? ", isValidIp('0.0.0.0'));
console.log("isValidIp('115.42.150.37') ? ", isValidIp('115.42.150.37'));
console.log("isValidIp('192.168.0.1') ? ", isValidIp('192.168.0.1'));
console.log("isValidIp('110.234.52.124' ? ", isValidIp('110.234.52.124'));
console.log("isValidIp('115.42.150.37') ? ", isValidIp('115.42.150.37'));
console.log("isValidIp('115.42.150.38') ? ", isValidIp('115.42.150.38'));
console.log("isValidIp('115.42.150.50') ? ", isValidIp('115.42.150.50'));
// Invalid
console.log("isValidIp('210.110') ? ", isValidIp('210.110'));
console.log("isValidIp('255') ? ", isValidIp('255'));
console.log("isValidIp('y.y.y.y' ? ", isValidIp('y.y.y.y'));
console.log(" isValidIp('255.0.0.y') ? ", isValidIp('255.0.0.y'));
console.log("isValidIp('666.10.10.20') ? ", isValidIp('666.10.10.20'));
console.log("isValidIp('4444.11.11.11') ? ", isValidIp('4444.11.11.11'));
console.log("isValidIp('33.3333.33.3') ? ", isValidIp('33.3333.33.3'));
/^(?!.*\.$)((?!0\d)(1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/
Full credit to oriadam. I would have commented below his/her answer to suggest the double zero change I made, but I do not have enough reputation here yet...
change:
-(?!0) Because IPv4 addresses starting with zeros ('0.248.42.223') are valid (but not usable)
+(?!0\d) Because IPv4 addresses with leading zeros ('63.14.209.00' and '011.012.013.014') can sometimes be interpreted as octal
Simple Method
const invalidIp = ipAddress
.split(".")
.map(ip => Number(ip) >= 0 && Number(ip) <= 255)
.includes(false);
if(invalidIp){
// IP address is invalid
// throw error here
}
Regular expression for the IP address format:
/^(\d\d?)|(1\d\d)|(0\d\d)|(2[0-4]\d)|(2[0-5])\.(\d\d?)|(1\d\d)|(0\d\d)|(2[0-4]\d)|(2[0-5])\.(\d\d?)|(1\d\d)|(0\d\d)|(2[0-4]\d)|(2[0-5])$/;
If you wrtie the proper code you need only this very simple regular expression: /\d{1,3}/
function isIP(ip) {
let arrIp = ip.split(".");
if (arrIp.length !== 4) return "Invalid IP";
let re = /\d{1,3}/;
for (let oct of arrIp) {
if (oct.match(re) === null) return "Invalid IP"
if (Number(oct) < 0 || Number(oct) > 255)
return "Invalid IP";
}
return "Valid IP";
}
But actually you get even simpler code by not using any regular expression at all:
function isIp(ip) {
var arrIp = ip.split(".");
if (arrIp.length !== 4) return "Invalid IP";
for (let oct of arrIp) {
if ( isNaN(oct) || Number(oct) < 0 || Number(oct) > 255)
return "Invalid IP";
}
return "Valid IP";
}
Throwing in a late contribution:
^(?!\.)((^|\.)([1-9]?\d|1\d\d|2(5[0-5]|[0-4]\d))){4}$
Of the answers I checked, they're either longer or incomplete in their verification. Longer, in my experience, means harder to overlook and therefore more prone to be erroneous. And I like to avoid repeating similar patters, for the same reason.
The main part is, of course, the test for a number - 0 to 255, but also making sure it doesn't allow initial zeroes (except for when it's a single one):
[1-9]?\d|1\d\d|2(5[0-5]|[0-4]\d)
Three alternations - one for sub 100: [1-9]?\d, one for 100-199: 1\d\d and finally 200-255: 2(5[0-5]|[0-4]\d).
This is preceded by a test for start of line or a dot ., and this whole expression is tested for 4 times by the appended {4}.
This complete test for four byte representations is started by testing for start of line followed by a negative look ahead to avoid addresses starting with a .: ^(?!\.), and ended with a test for end of line ($).
See some samples here at regex101.
This is what I did and it's fast and works perfectly:
function isIPv4Address(inputString) {
let regex = new RegExp(/^(([0-9]{1,3}\.){3}[0-9]{1,3})$/);
if(regex.test(inputString)){
let arInput = inputString.split(".")
for(let i of arInput){
if(i.length > 1 && i.charAt(0) === '0')
return false;
else{
if(parseInt(i) < 0 || parseInt(i) >=256)
return false;
}
}
}
else
return false;
return true;
}
Explanation: First, with the regex check that the IP format is correct. Although, the regex won't check any value ranges.
I mean, if you can use Javascript to manage regex, why not use it?. So, instead of using a crazy regex, use Regex only for checking that the format is fine and then check that each value in the octet is in the correct value range (0 to 255). Hope this helps anybody else. Peace.
And instead of
{1-3}
you should put
{1,3}
\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b
matches 0.0.0.0 through 999.999.999.999
use if you know the seachdata does not contain invalid IP addresses
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
use to match IP numbers with accurracy - each of the 4 numbers is stored into it's own capturing group, so you can access them later
it is maybe better:
function checkIP(ip) {
var x = ip.split("."), x1, x2, x3, x4;
if (x.length == 4) {
x1 = parseInt(x[0], 10);
x2 = parseInt(x[1], 10);
x3 = parseInt(x[2], 10);
x4 = parseInt(x[3], 10);
if (isNaN(x1) || isNaN(x2) || isNaN(x3) || isNaN(x4)) {
return false;
}
if ((x1 >= 0 && x1 <= 255) && (x2 >= 0 && x2 <= 255) && (x3 >= 0 && x3 <= 255) && (x4 >= 0 && x4 <= 255)) {
return true;
}
}
return false;
}
The answers over allow leading zeros in Ip address, and that it is not correct.
For example ("123.045.067.089"should return false).
The correct way to do it like that.
function isValidIP(ipaddress) {
if (/^(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)\.(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)\.(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)\.(25[0-5]|2[0-4][0-9]|[1]?[1-9][1-9]?)$/.test(ipaddress)) {
return (true)
}
return (false) }
This function will not allow zero to lead IP addresses.
Always looking for variations, seemed to be a repetitive task so how about using forEach!
function checkIP(ip) {
//assume IP is valid to start, once false is found, always false
var test = true;
//uses forEach method to test each block of IPv4 address
ip.split('.').forEach(validateIP4);
if (!test)
alert("Invalid IP4 format\n"+ip)
else
alert("IP4 format correct\n"+ip);
function validateIP4(num, index, arr) {
//returns NaN if not an Int
item = parseInt(num, 10);
//test validates Int, 0-255 range and 4 bytes of address
// && test; at end required because this function called for each block
test = !isNaN(item) && !isNaN(num) && item >=0 && item < 256 && arr.length==4 && test;
}
}
In addition to a solution without regex:
const checkValidIpv4 = (entry) => {
const mainPipeline = [
block => !isNaN(parseInt(block, 10)),
block => parseInt(block,10) >= 0,
block => parseInt(block,10) <= 255,
block => String(block).length === 1
|| String(block).length > 1
&& String(block)[0] !== '0',
];
const blocks = entry.split(".");
if(blocks.length === 4
&& !blocks.every(block => parseInt(block, 10) === 0)) {
return blocks.every(block =>
mainPipeline.every(ckeck => ckeck(block) )
);
}
return false;
}
console.log(checkValidIpv4('0.0.0.0')); //false
console.log(checkValidIpv4('0.0.0.1')); //true
console.log(checkValidIpv4('0.01.001.0')); //false
console.log(checkValidIpv4('8.0.8.0')); //true
This should work:
function isValidIP(str) {
const arr = str.split(".").filter((el) => {
return !/^0.|\D/g.test(el);
});
return arr.filter((el) => el.length && el >= 0 && el <= 255).length === 4;
}
well I try this, I considered cases and how the entries had to be:
function isValidIP(str) {
let cong= /^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/
return cong.test(str);}
A less stringent when testing the type not the validity. For example when sorting columns use this check to see which sort to use.
export const isIpAddress = (ipAddress) =>
/^((\d){1,3}\.){3}(\d){1,3}$/.test(ipAddress)
When checking for validity use this test. An even more stringent test checking that the IP 8-bit numbers are in the range 0-255:
export const isValidIpAddress = (ipAddress) =>
/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipAddress)

Categories

Resources