regular expression for ip v4 - javascript

I am doing an ip v4 validator program with javascript.
The ip has to be between the range of 1.0.0.0 to 255.255.255.255
My problem is that I also get the 0.0.0.0 and should not take it.
I leave you my regular expression:
Var Expression1 = new RegExp ("[0-9] | [1-9] [0-9] | 1 [0-9] {2} | 2 [0-4] [0-9] | 25 [0-5]) [3] ([0-9] | [1-9] [0-9] | 1 [0-9] {2} | 2 [0-4] [0-9] ] | 25 [0-5]) $ ");
Thank you!

Add "not 0.0.0.0" negative lookbehind (^(?!0\.0\.0\.0)) at the beginning of the line:
^(?!0\.0\.0\.0)(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$
Demo: https://regex101.com/r/dIkHRJ/2
P.S.
Please notice your regex is incomplete and broken. Use the corrected one from the sample above.

Why not use a function, it will be clearer not using a regex:
function validateIP(ip) {
var p = ip.split('.'); // split it by '.'
if(p.length !== 4) return false; // if there is not for parts => false
for(var i = 0; i < 4; i++) // for each part
if(isNaN(p[i]) || i < 0 || i > 255) return false; // if it's not a number between 0 - 255 => false
return p[3] > 0; // return true if the last part is not 0, false otherwise
}
alert(validateIP(prompt("IP: ")));

The more accurate solution using RegExp.prototype.test(), String.prototype.split() and Array.prototype.every() functions:
var re = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,
validateIPv4 = function(ip) {
return re.test(ip) && ip.split('.').every(function(d, idx){
var octet = Number(d);
if (idx === 0) {
return octet > 0;
}
return 0 <= octet && octet <= 255;
});
};
console.log(validateIPv4('0.0.0.0'));
console.log(validateIPv4('1.0.0.0'));
console.log(validateIPv4('127.0.0.1'));
console.log(validateIPv4('255.255.255.255'));

Related

Can't convert string into number

I have a large text from which I read data according to the scheme. Key words are placed in the "smallArtName" array. The scheme looks like this:
(key word) xxx (cordX|cordY)
I can't convert the string I received to a number. It seems to me that the reason is white space, visible in the terminal in the picture. I tried to use the replace method which works for sample text, but not for my value.
I'm a beginner and I could probably do it simpler, but the code I wrote works, and this is the most important thing for now.
for (i = 0; i < smallArtName.length; i++) {
var n = art.artPrintScreen.indexOf(smallArtName[i]);
if (n > -1) {
var tempString = art.artPrintScreen.substring(n, n + 100);
betweenChar = tempString.indexOf('|');
for (k = betweenChar - 10; k <= betweenChar + 10; k++) {
if (tempString[k] == '(') {
xStart = k;
}
if (tempString[k] == ')') {
yEnd = k;
}
}
cordX = tempString.slice(xStart + 1, betweenChar);
cordY = tempString.slice(betweenChar + 1, yEnd);
strTest = " t est".replace(/\s/g, '')
var cordY2 = cordY.replace(/\s/g, '')
console.log(typeof (cordY))
console.log(cordY2)
console.log(cordY2[0])
console.log(cordY2[1])
console.log(cordY2[2])
console.log(cordY2[3])
console.log(cordY2[4])
console.log(cordY2[5])
console.log(strTest)
var cordYtest = parseInt(cordY2, 10);
console.log(cordYtest)
}
}
Terminal:
-181
-
1
8
1
test
NaN
string
-154
-
1
5
4
test
NaN
string
104
1
0
4
undefined
test
NaN
Fragment of input text:
Ukryta twierdza (Mapa podziemi I) 153 ‭(‭−‭72‬‬|‭−‭155‬‬)‬
Ukryta twierdza (Amfora Mgły VI) 135 ‭(‭73‬|‭104‬)‬
Ukryta twierdza (Mapa podziemi IV) 131 ‭(‭154‬|‭−‭72‬‬)‬
Analysing your sample input strings, I found some unicode characters \u202c and \u202d that should be stripped before converting to number. Also, the negative values are prefixed by the character −, which is different than minus -, se we need to replace it. That being said, all parsing could be done with a single regex:
var input = "Ukryta twierdza (Mapa podziemi I) 153 ‭(‭−‭72‬‬|‭−‭155‬‬)‬";
input = input.replace(/\u202d|\u202c/g, "");
input = input.replace(/−/g, "-");
var m = input.match(/.*\((.*)\)\s*(.+?)\s*\((.+)\|(.+)\)/);
console.log(m);
console.log(parseInt(m[3]));
console.log(parseInt(m[4]));
Explaining the regex:
.* - Something that will be ignored
\((.*)\) - Something enclosed in parenthesis
\s*(.+?)\s* - Something possibly surrounded by spaces
\((.+)\|(.+)\) - Two parts split by a | and enclosed by parenthesis

How can I split a string and get just key part with regexp?

I have a string like "A < -5.9 AND B >= 6 OR (C < 3)" I have to get keys part.(A,B,C). So I thought I should split first AND and OR then I should get key part? Could you help me? I wrote just A,B,C but in my real example A can be any string. The important thing is that is value on the right side of
<,>,<=,>=
Simplest way would be to split using a regex:
"A < -5.9 AND B >= 6 OR (C < 3)".split(/ AND | OR /);
// ["A < -5.9", "B >= 6", "(C < 3)"]
We can try doing a regex search for all matches on the pattern:
\b([A-Z]+) \S+ -?\d+(?:\.\d+)?\b
Sample script:
var regex = /\b([A-Z]+) \S+ -?\d+(?:\.\d+)?\b/g;
var input = "A < -5.9 AND B >= 6 OR (C < 3)";
var m;
do {
m = regex.exec(input);
if (m) {
console.log(m[1]);
}
} while (m);
Here is an explanation of the regex pattern being used:
\b([A-Z]+) match and capture a key as one or more capital letters
\S+ match space followed by a symbol and another space
-?\d+ match a number with optional negative sign
(?:\.\d+)?\b match an optional decimal component
Without regex you caniterate the string and match the character > or <. If the character matches then create a substring and then get the last character of the substring. Also note trim() will remove any white space from the string
let str = 'A < -5.9 AND B >= 6 OR (C < 3)';
let arr = [];
for (let i = 0; i < str.length; i++) {
if (str[i] === '<' || str[i] === '>') {
let subStr = str.substring(0, i).trim();
arr.push(subStr.charAt(subStr.length - 1))
}
};
console.log(arr);
If it's just a matter of capturing variable names that appear to the left of a comparison operator:
const s = "A < -5.9 AND B >= 6 OR (C < 3)";
const variables = s.match(/\w+(?=\s*[<>])/g);
console.log(variables);

Regular Expression doesn't count characters that are part of * quantifier

the regular expression: /([a-z][0-9]*){6,12}/i
so i am expecting this to return true if a string contains more than 6 and less than 12 characters even if there aren't 6 alphabetical characters, but it doesn't, i want "123456789a" to return true and "abcdefghi1", but the first one doesn't.
var myRegEx = /([a-z][0-9]*){6,12}/i;
function checkIt() {
var myString = document.getElementsByTagName("input")[0].value;
if(myRegEx.test(myString) == true) {
document.getElementsByTagName("p")[0].className = "trueOrFalse true";
document.getElementsByTagName("p")[0].innerHTML = "True";
}
else {
document.getElementsByTagName("p")[0].className = "trueOrFalse false";
document.getElementsByTagName("p")[0].innerHTML = "False";
}
}
https://jsfiddle.net/y71mudms/2/
the correct regex is
var myRegEx = /^[0-9]{6,11}[a-z]{1}$/i;
we search exact match of digits + 1 char from 6 to 12
/^[0-9]{6,11}[a-z]{1}$/i;
^ ^ ^ ^
| | | |_ end of string
| | |
| | |_ from 6 min to 11 max repetitions
| |
| |_ digit 0-9 include all digits
|
|_ begin of string
ref. 6 digits regular expression
Just wrap a check for the string-length around your regex-conditions:
if string.length > 6 && string.length < 12) {
// if regex...
}

Regex for hexa decimal combination of string

I need a regex which will test the combination of hexadecimal string. Specifically, the string must have:
Atleast one digit in the range 0 - 9,
At least one digit in the range A - F,
be 12 characters long.
String should not start with 0
Currently I am using var macRegex = new RegExp("^[0-9A-Fa-f]{12}$");. The above regex allow strings like "111111111111" , "000000000000" which i want to avoid . It should allow a string like "944a0c122123"
How can I accomplish this?
To keep the regular expression simple, I'd separate matching the pattern and checking the length:
var re = /^(\d+[a-f]+[\da-f]*|[a-f]+\d+[\da-f]*)$/i;
var s = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // true
var s = '000000000000';
console.log(re.test(s) && s.length == 12); // false
The pattern to match:
one or more digits followed by one or more letters a to f followed by zero or more digits or letters a to f, OR
one or more letters a to f followed by one or more digits followed by zero or more digits or letters a to f
then check the length is 12.
Edit
To meet the new criterion "can't start with 0" (and simplify the expression a bit), the regular expression can be:
var re = /^([1-9]\d*[a-f]+|[a-f]+\d+)[\da-f]*$/i;
var s = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // false
var s = '000000000000';
console.log(re.test(s) && s.length == 12); // false
var s = '011001aFFA77';
console.log(re.test(s) && s.length == 12); // false
var s = 'a11001aFFA77';
console.log(re.test(s) && s.length == 12); // true
var s = '311001aFFA77';
console.log(re.test(s) && s.length == 12); // true
var s = '0000000000a1';
console.log(re.test(s) && s.length == 12); // false
If you don't mind a non RegExp solution this function should do what you want.
function only_hex_len_12(str){
// if the string is the wrong length return false
if(str.length!=12) return false;
var hex_val=parseInt(str,16);
var dec_val=parseInt(str,10);
// If the string is dec return false
if(!isNaN(dec_val)) return false;
// If the string is not hex return false
if(isNaN(hex_val)) return false;
// Otherwise the string is okay so return true
return true;
}
If you want a RegExp solution RobG's answer looks good.
Here is the way I'd go:
/^(?=.*\d)(?=.*[a-f])[1-9a-f][\da-f]{10}[1-9a-f]$/i
Explanation:
/
^ : begining of string
(?=.*\d) : lookahead, at least one digit
(?=.*[a-f]) : lookahead, at least one letter in range a-f
[1-9a-f] : first character, not zero
[\da-f]{10} : ten hex character
[1-9a-f] : last character, not zero
$ : end of string
/i : case insensitive
You can use a set of positive lookaheads to do this.
Here's the regex:
/(?!0).(?=.*\d)(?=.*[a-f])[\da-f]{11}/i
(?!0) Negative lookahead
. Match any character
(?= Positive lookahead
.* Match any character zero to unlimited
\d Match a digit
)
(?= Positive lookahead
.* Match any character zero to unlimited
[a-f] Match a character a-f
)
[\da-f]{11} Match any of the valid characters, 12 times
You can conceptualize this is a logical AND of the expressions in each lookahead (except for the .*).
var regexp = /(?!0).(?=.*\d)(?=.*[a-f])[\da-f]{11}/i;
var test1 = "000000000000";
var test2 = "111111111111";
var test3 = "8179acf0871a";
var test4 = "9abzzzzzzzzz";
var test5 = "0179acf0871a";
console.log(regexp.test(test1));
console.log(regexp.test(test2));
console.log(regexp.test(test3));
console.log(regexp.test(test4));
console.log(regexp.test(test5));
Here's a snippet that demonstrates similar input samples.

How to insert new line after N char count in javascript?

I have a string which may have new line '\n' char in it. Now I want to insert new line '\n' after every 4 (or N) chars in that string.
For example:
1)
INPUT: "I am John Doe."
OUTPUT: "I am\nJohn\nDoe"
In above example inserting '\n' after 4 char including space
2)
INPUT: "I\nam John Doe"
OUTPUT: "I\nam J\nohn \nDoe"
In above example inserting space after 4 chars after first '\n' already present in the string
3)
INPUT: 12345\n67890
OUTPUT: 1234\n5\n6789\n0
4)
INPUT: "1234\n56\n78901"
OUTPUT: "1234\n56\n7890\n1"
So far I have created a function which inserts '\n' after every 4 chars but it does not consider '\n' if it is already present in the original string.
function addNewlines(str) {
if (str.length >= 4) {
var result = '';
while (str.length > 0) {
result += str.substring(0, 4) + '\n';
str = str.substring(4);
}
return result;
}
return str;
}
I call this function on every keypress and pass the original string and get output and use it further. I hope you understand what I meant to say here. It should preserve the previously inserted new lines.
Let me know I can explain further. With more examples.
Here is my best guess as to what is being asked for :
function addNewLines (str) {
return str.replace (/(?!$|\n)([^\n]{4}(?!\n))/g, '$1\n');
}
Some test strings and their results :
"I am John Doe.", -> "I am\n Joh\nn Do\ne."
"I\nam John Doe", -> "I\nam J\nohn \nDoe"
"12345\n67890", -> "1234\n5\n6789\n0"
"1234\n56\n78901", -> "1234\n56\n7890\n1"
"ABCD\nEFGH\nIJKL", -> "ABCD\nEFGH\nIJKL\n"
"1234", -> "1234\n"
"12341234" -> "1234\n1234\n"
For those of you for whom regular expressions are mysterious here is a breakdown:
---------------------------- (?! Check that following character(s) are not
| ------------------------- $|\n Beginning of string or a newline character
| | --------------------- )
| | | -------------------- ( Start of capture group 1
| | || ------------------ [^\n] Any single character other than newline
| | || | -------------- {4} Previous element repeated exactly 4 times
| | || | | ----------- (?! Check that following character(s) are not
| | || | | | --------- \n a newline
| | || | | | | ------- )
| | || | | | | |------ ) End of capture group 1
| | || | | | | || ---- /g in replace causes all matches to be processed
| | || | | | | || |
/(?!$|\n)([^\n]{4}(?!\n))/g
function parseInput(str, char, length){
var split = str.split(char),
regex = RegExp('(.{' + length + '})','g');
split[split.length-1] = split[split.length - 1].replace(regex, '$1' + char);
return split.join(char);
}
console.log(parseInput("I am John Doe.", "\n", 4));
// output = "I am\n Joh\nn Do\ne."
Split the string by "\n" str.split("\n"). You get an array of strings.
Do your additional parsing and manipulation checking the element length and putting the result in a new array results.
Join the strings using results.join("\n").
This will remove "\n" duplicates too if you avoid to append or prepend "\n" to results elements.
Here is my code:
function ngram_insert (n, ins, input)
{
var output = "";
var i = 0;
while (i < strlen(input))
{
if (i > 0 && i % n == 0)
{
output += ins;
}
output += input[i];
i++;
}
return output;
}
Test:
var output = ngram_insert (3, "\n", "This is a test.");
function f(n, ins, str) {
if (str.length == 0)
return "";
var i = str.indexOf("\n"), len = str.length, newStr;
if (i == -1) {
i = 1;
newStr = str[0];
}
else {
newStr = str.substring(0, i + 1);
}
var k = 1;
while (k + i < len) {
newStr += str[k + i];
if (k % n == 0) {
newStr += ins;
}
k++;
}
return newStr;
}
Calling f(4, "\n", "I\nam John Doe"); returns "I\nam J\nohn \nDoe"

Categories