Regexp to validate ip address with last digit as non zero - javascript

I have a regex that i ended up using from one of the answer here in SO .
Basically my regex must validate ipv4 address with mask .
So i ended up using the below regex :
(?:(?: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]?)/([1-9]|1[0-9]|2[0-9]|3[0-2]|(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254))))
Now my challenge is to not allow 0 in the last digit of ip i.e ,
192.168.6.10/mask is valid but 192.168.6.0/mask is invalid
So i modified the above regexp to something like this :
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[1][0-9][0-9]|[1-9][0-9]|[1-9]?)/([1-9]|1[0-9]|2[0-9]|3[0-2]|(((128|192|224|240|248|252|254)\.0\.0\.0)|(255\.(0|128|192|224|240|248|252|254)\.0\.0)|(255\.255\.(0|128|192|224|240|248|252|254)\.0)|(255\.255\.255\.(0|128|192|224|240|248|252|254))))
but 192.168.6.0 is always valid when testing with Angular Validators.pattern
Any idea where i'm going wrong ?
EDIT
List of IPs & its validity :
192.168.6.6/24 is valid
192.168.6.6/24 is valid
192.168.6.24/24 is valid
192.168.6.0/24 invalid
192.168.6.0/255.255.255.0 is invalid

You want to avoid matching any IP with the last octet set to 0.
You may use
ipAddress : FormControl = new FormControl('' , Validators.pattern(/^(?!(?:\d+\.){3}0(?:\/|$))(?:(?: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]?)\/(?:[1-9]|1[0-9]|2[0-9]|3[0-2]|(?:(?:128|192|224|240|248|252|254)\.0\.0\.0|255\.(?:0|128|192|224|240|248|252|254)\.0\.0|255\.255\.(?:0|128|192|224|240|248|252|254)\.0|255\.255\.255\.(?:0|128|192|224|240|248|252|254)))$/));
Here is the regex demo
The main addition is the lookahead after ^ that is executed once at the start of a string. The (?!(?:\d+\.){3}0(?:\/|$)) pattern is a negative lookahead that fails the match if, immediately to the right of the current location (string start), there are:
(?:\d+\.){3} - three repetitions of 1+ digits and a dot
0 - a zero
(?:\/|$)) - / or (|) end of string ($).
Notice I defined the pattern using a regex literal notation (/regex/) and I had to add ^ (string start) and $ (string end) anchors since the regex was no longer anchored by default. Also, to escape special chars in a regex literal notation, you only need one backslash, not two.

Suppose that the last part cannot be written 000 and 00 but just 0. Then you can you such regex
^(?:(?:2(?:5[0-5]|[0-4]\d)|1?\d?\d)\.){3}(?:(?:2(?:5[0-5]|[0-4]\d)|1?\d\d|[1-9]))$
Where diff between the first groups and the last one that one-digit value should be from 1 to 9
demo

You can try with this pattern
^(?:[1-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(?:[1-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(?:[1-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(?:2[0-5][1-5]|[1-9]|1[0-9][1-9]|[1-9][1-9])$
Online demo
For the last numbers you have check with this
(?:2[0-5][1-5]|[1-9]|1[0-9][1-9]|[1-9][1-9])

One possible approach here is simple, and just involves adding a negative lookbehind at the very end of the pattern (?<!\.0), which asserts that .0 is not the immediately preceding term in the IP address. Applying this to your correctly working pattern from the comments above, we get:
^(?:(?: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]?)\/
([1-9]|1[0-9]|2[0-9]|3[0-2]|(((128|192|224|240|248|252|254)\.0\.0\.0)|
(255\.(0|128|192|224|240|248|252|254)\.0\.0)|
(255\.255\.(0|128|192|224|240|248|252|254)\.0)|
(255\.255\.255\.(0|128|192|224|240|248|252|254))))(?<!\.0)$
Demo
The downside is that your JavaScript engine may not yet support negative lookbehind syntax just yet.

Related

Regex for float matching strings like "12." also?

I tried with this regex to match floating values:
(^\d{0,11}$)|^\d{0,11}([.]\d{0,6})?$
However, I don't want to allow strings like 12., i.e. a number with a dot at the end.
Please me give me a suggestion.
You may use
^\d{0,11}(?:\.\d{1,6})?$
If you use \d{0,6}, the pattern may match an empty string. Note that it is not recommended to test JS regex with RegexStorm.net as it only supports .NET regex and uses CRLF line endings.
Details
^ - start of string
\d{0,11} - zero to eleven digits
(?:\.\d{1,6})? - an optional sequence of
\. - a dot
\d{1,6} - 1 to 6 digits
$ - end of string.
See the regex demo.
How about you restrict the count of the decimal part.. like this
^\d{0,11}(?:\.\d{1,6})?$

Regular Expression for Blocking a character in begining

I am facing an issue with a regular expression while trying to block any string which has minus(-) in the beginning of some white listed characters.
^(?!-.*$).([a-zA-Z0-9-:#\\,()\\/\\.]+)$
It is blocking minus(-) at place and allowing it any where in the character sequence but this regex is not working if the passed string is single character.
For e.g A or 9 etc.
Please help me out with this or give me a good regex to do the task.
Your pattern requires at least 2 chars in the input string because there is a dot after the first lookahead and then a character class follows that has + after it (that is, at least 1 occurrence must be present in the string).
So, you need to remove the dot. Also, you do not need to escape any special char inside a character class. Besides, to avoid matching strings atarting with - a mere (?!-) will suffice, no need adding .*$ there. You may use
^(?!-)[a-zA-Z0-9:#,()/.-]+$
See the regex demo. Remember to escape / if used in a regex literal notation in JavaScript, there is no need to escape it in a constructor notation or in a Java regex pattern.
Details
^ - start of a string
(?!-) - cannot start with -
[a-zA-Z0-9:#,()/.-]+ - 1 or more ASCII letters, digits and special chars defined in the character class (:, #, ,, (, ), /, ., -)
$ - end of string.
If i understand correctly, and you don't want a minus at the beginning, does ^[^-].* work as a regex for you? Java's "matches" would return false if it starts with minus
There is a method in a String class that provides you exactly what you are asking for - it's a startsWith() method - you could use this method in your code like this (you can translate it as "If the given String doesn't start with -, doSomething, in other case do the else part, that can contain some code or might be empty if you want nothing to be done if the given String starts with - ") :
if(!(yourString.startsWith("-"))) {
doSomething()
} else {
doNothingOrProvideAnyInformationAboutWrongInput()
}
I think that it can help you.
^(?!-).*[a-zA-Z0-9-:#\\,()\/\\.]+$

Regex to match char after string

I'm attempting to match the first 3 letters that could be a-z followed by a specific character.
For testing I'm using a regex online tester.
I thought this should work (without success):
^[a-z]{0,3}$[z]
My test string is abcz.
Hope you can tell me what I'm doing wrong.
If you need to match a whole string abcz, use
/^[a-z]{0,3}z$/
^^
or - if the 3 letters are compulsory:
/^[a-z]{3}z$/
See the regex demo.
The $[z] in your pattern attempts to match a z after the end of string anchor, which makes the regex fail always.
Details:
^ - string start
[a-z]{0,3} - 0 to 3 lowercase ASCII letters (to require 3 letters, remove 0,)
z - a z
$ - end of string anchor.
You've got the end of line identifier too early
/^[a-z]{0,3}[z]$/m
You can see a working version here
You can do away with the [] around z. Square brackets are used to define a range or list of characters to match - as you're matching only one they're not needed here.
/^[a-z]{0,3}z$/m

Regex - I keep getting "Nothing to repeat" exception

I use this regex code to parse urls:
/^(((http|https):\/\/)+[www.])?+\s*\S+\s*+(.com|.es|.net|.org|.co)$/ig
It works perfectly on https://regex101.com/r/bX5oM4/1
But on my console I keep getting the:
SyntaxError: Invalid regular expression: /^(((http|https):\/\/)+[www\.])?+\s*\S+\s*+(\.com|\.es|\.net|\.org|\.co)$/: Nothing to repeat
I tried escaping the + but It doesn't work. I'm kinda new on regex so It could be anything.
Here is your fixed regex:
^(?:https?:\/\/www\.)?[a-zA-Z0-9]\S+(\.(?:com|es|net|org|co))$
See demo
Or, to match the strings inside larger strings:
\b(?:https?:\/\/www\.)?[a-zA-Z0-9]\S+(?:\.(?:com|es|net|org|co))\b
See another demo
In JavaScript, you cannot set + to ? quantifier.
Also, note that [www.] matches 1 character, either w or . since it is a character class. You must have meant a group, and thus you need round brackets, not square ones.
I removed unnecessary groups, regrouped them a bit and escaped the dots. Note that unescaped dot matches any character but a newline.
So, the regex:
^ - Asserts the position at the start of the string
(?:https?:\/\/www\.)? - Optionally matches http or https then //www. literally
\w\S+ - 1 alhoanumeric and 1 or more non-whitespace characters
(\.(?:com|es|net|org|co)) - Matches a dot and then any of the alternatives in the round brackets
$ - Asserts end of string
Try this (update!)
^((http|https):\/\/)?([\w]+[.-]?)+\.(com|es|net|org|co|uk|de)$
instead of
/^(((http|https):\/\/)+[www.])?+\s*\S+\s*+(.com|.es|.net|.org|.co)$/ig
You had an extra + behind a ? and another one behind a *. And several other things were not quite OK, as stribizhev pointed out quite rightly!
This regex is looking for a limited range of TLDs ... (e. g. french pages would not pass). The [www.] was syntactically wrong and also surperfluous as any domain name can have subdomains (expressed by ([\w]+[.-]?)+) and 'www.' is just one of the possible ones.

UK Currency Regular Expression for javascript

I'm after a regular expression that matches a UK Currency (ie. £13.00, £9,999.99 and £12,333,333.02), but does not allow negative (-£2.17) or zero values (£0.00 or 0).
I've tried to create one myself, but I've got in a right muddle!
Any help greatfully received.
Thanks!
This'll do it (well mostly...)
/^£?[1-9]{1,3}(,\d{3})*(\.\d{2})?$/
Leverages the ^ and $ to make sure no negative or other character is in the string, and assumes that commas will be used. The pound symbol, and pence are optional.
edit: realised you said non-zero so replaced the first \d with [1-9]
Update: it's been pointed out the above won't match £0.01. The below improvement will but now there's a level of complexity where it may quite possibly be better to test /[1-9]/ first and then the above - haven't benchmarked it.
/^£?(([1-9]{1,3}(,\d{3})*(\.\d{2})?)|(0\.[1-9]\d)|(0\.0[1-9]))$/
Brief explanation:
Match beginning of string followed by optional "£"
Then match either:
a >£1 amount with potential for comma separated groupings and optional pence
OR a <£1 >=£0.10 amount
OR a <=£0.09 amount
Then match end of line
The more fractions of pence (zero in the above) you require adding to the regex the less efficient it becomes.
Under Unix/Linux, it's not always possible to type in the '£' sign in a JavaScript file, so I tend to use its hexadecimal representation, thus:
/^\xA3?\d{1,3}?([,]\d{3}|\d)*?([.]\d{1,2})?$/
This seems to take care of all combinations of UK currency amounts representation that I have come across.
/^\xA3?\d{1,}(?:\,?\d+)*(?:.\d{1,2})?$/;
Explanation:
^ Matches the beginning of the string, or the beginning of a line.
xA3 Matches a "£" character (char code 163)
? Quantifier for match between 0 and 1 of the preceding token.
\d Matches any digit character (0-9).
{1,} Match 1 or more of the preceding token.
(?: Groups multiple tokens together without creating a capture group.
\, Matches a "," character (char code 44).
{1,2} Match between 1 and 2 of the preceding token.
$ Matches the end of the string, or the end of a line if the multiline flag (
You could just make two passes:
/^£\d{1,3}(,\d{3})*(\.\d{2})?$/
to validate the format, and
/[1-9]/
to ensure that at least one digit is non-zero.
This is less efficient than doing it in one pass, of course (thanks, annakata, for the benchmark information), but for a first implementation, just "saying what you want" can significantly reduce developing time.

Categories