Conditional regex javascript - javascript

I'm trying to make a regex which can match a phone number and so tell me if the phone number is either valid or not.
I would like to verify if there is a country id before the phone number, this one is well formated.
For example : +(33)0123456789 I want to be sure if the user start to type the first parenthesis it must be followed by number and ended by a closing parenthesis.
I have succeeded with PCRE engine
^[+]?((\()?(?(2)[0-9]{1,4})(?(2)\)))?([0-9]{2}){1}([\.\- ]?[0-9]{2}){4}$
But I realized this way doesn't work with javascript engine, conditional is not supported.
^[+]?((\()?((?=\2)[0-9]{1,4})((?=\2)\)))?([0-9]{2}){1}([\.\- ]?[0-9]{2}){4}$
It doesn't fill my needs. I want to check if the first parenthesis is set then it must be followed by number and a closing parenthesis.
So I ask you if there is a workaround in javascript to do this ?
Some help would be really appreciated, thank you :)

The ((\()?(?(2)[0-9]{1,4})(?(2)\)))? part of the regex is matching an optional sequence of smaller patterns. (\()? matches an optional ( and places it in Group 2. Then, (?(2)[0-9]{1,4}) matches 1 to 4 digits if Group 2 matched. Then (?(2)\)) matches ) if Group 2 matched. Basically, this is equal to (?:\([0-9]{1,4})\))?.
Thus, you need no conditional construct here.
You may use
^\+?(?:\([0-9]{1,4})\)?[0-9]{2}(?:[. -]?[0-9]{2}){4}$
See the regex demo
Details
^ - start of string
\+? - an optional +
(?:\([0-9]{1,4})\)? - an optional sequence: (, 1 to 4 digits and )
[0-9]{2} - 2 digits
(?:[. -]?[0-9]{2}){4} - 4 occurrences of an optional space, dot or - followed with 2 digits
$ - end of string.

Related

Regular Expressions: Positive and Negative Lookahead Solution

I was doing Freecodecamp RegEx challange, which's about:
Use lookaheads in the pwRegex to match passwords that are greater than 5 characters long, do not begin with numbers, and have two consecutive digits
So far the solution I found passed all the tests was:
/^[a-z](?=\w{5,})(?=.*\d{2}\.)/i
However, when I tried
/^[a-z](?=\w{5,})(?=\D*\d{2,}\D*)/i
I failed the test trying to match astr1on11aut (but passed with astr11on1aut). So can someone help me explaining how ?=\D*\d{2,}\D* failed this test?
So can someone help me explaining how (?=\D*\d{2,}\D*) failed this
test?
Using \D matches any char except a digit, so from the start of the string you can not pass single digit to get to the 2 digits.
Explanation
astr1on11aut astr11on1aut
^ ^^
Can not pass 1 before reaching 11 Can match 2 digits first
Note
the expression could be shortened to (?=\D*\d{2}) as it does not matter if there are 2, 3 or more because 2 is the minimum and the \D* after is is optional.
the first expression ^[a-z](?=\w{5,})(?=.*\d{2}\.) can not match the example data because it expects to match a . literally after 2 digits.
Failed for the \d{2,}
Then let's have a look at the regexp match process
/^[a-z](?=\w{5,})
means start with [a-z], the length is at least 6, no problem.
(?=\D*\d{2,}\D*)
means the first letter should be followed by these parts:
[0 or more no-digit][2 or more digits][0 or more no-digits]
and lets have a look at the test case
astr1on11aut
// ^[a-z] match "a"
// length matchs
// [0 or more no-digit]: "str"
// d{2,} failed: only 1 digit
the ?= position lookahead means exact followed by.
The first regular expression is wrong, it should be
/^[a-z](?=\w{5,})(?=.*\d{2}.*)/i
When it comes to lookahead usage in regex, rememeber to anchor them all at the start of the pattern. See Lookarounds (Usually) Want to be Anchored. This will help you avoid a lot of issues when dealing with password regexps.
Now, let's see what requirements you have:
"are greater than 5 characters long" => (?=.{6}) (it requires any 6 chars other than lien break chars immediately to the right of the current location)
"do not begin with numbers" => (?!\d) (no digit allowed immediately to the right)
have two consecutive digits => (?=.*\d{2}) (any two digit chunk of text is required after any 0 or more chars other than line break chars as many as possible, immediately to the right of the current location).
So, what you may use is
^(?!\d)(?=.{6})(?=.*\d{2})
Note the most expensive part is placed at the end of the pattern so that it could fail quicker if the input is non-matching.
See the regex demo.

Forcing a Strict Character Order in a Regex Expression

I'm trying to create a regex in Javascript that has a limited order the characters can be placed in, but I'm having trouble getting the validation to be fully correct.
The criteria for the expression is a little complicated. The user must input strings with the following criteria:
The string contains two parts, an initial group, and an end group.
The groups are separated by a colon (:).
Strings are separated by a semi-colon (;).
The initial group can start with one optional forward-slash and end with one optional forward-slash, but these forward-slashes may not appear anywhere else in the group.
Inside forward-slashes, one optional underscore may appear on either end, but they may not appear anywhere else in the group.
Inside these optional elements, the user may enter any number of numbers or letters, uppercase or lowercase, but exactly one of these characters must be surrounded with angular brackets (<>).
If the letter inside the brackets is an uppercase C, it may be followed by one of a lowercase u or v.
The end group may contain one or more of a number or letter, uppercase or lowercase (If it is an uppercase C, it can be followed by a lowercase u or v.) or one asterisk (*), but not both.
A string must be able to validate with multiple groupings.
This probably sounds a little confusing.
For example, the following examples are valid:
<C>:Cu;
<Cu>:Cv;
/_V<C>V:C;
/_VV<Cv>VV_/:Cu;
_<V>:V1;
_<V>_:V1;
_<V>/:V1;
_<V>:*;
_<m>:n;
The following are invalid:
Cu:Cv;
Cu:Cv
CuCv;
<Cu/>:Cv;
<Cu_>:Cv;
<Cu>:Cv/;
_/<Cu>:Cv;
<Cu>/_:Cv;
They should validate when grouped together like so.
<Cu>:Cv;/_V<C>V:C;_<V>:V1;_<V>/:V1;_<V>:*;_<m>:n;
Hopefully, these examples help you understand what I'm trying to match.
I created the following regexp and tested it on Regex101.com, but this is the closest I could come:
\\/{0,1}_{0,1}[A-Za-z0-9]{0,}<{1}[A-Za-z0-9]{1,2}>{1}[A-Za-z0-9]{0,}_{0,1}\\/{0,1}):([A-Za-z0-9]{1,2}|\\*;$
It's mostly correct, but it allows strings that should be invalid such as:
_/<C>:C;
If an underscore comes before the first forward-slash, it should be rejected. Otherwise, my regexp seems to be correct for all other cases.
If anyone has any suggestions on how to fix this, or knows of a way to match all criteria much more efficiently, any help is appreciated.
The following seems to fulfill all the criteria:
(?:^|;)(\/?_?[a-zA-Z0-9]*<(?:[a-zA-Z]|C[uv]?)>[a-zA-Z0-9]*_?\/?):([a-zA-Z0-9]+|\*)(?=;|$)
Regex101 demo.
It puts each of the "groups" in a capturing group so you can access them individually.
Details:
(?:^|;) A non-capturing group to make sure the string is either at the beginning or starts with a semicolon.
( Start of group 1.
\/?_? An optional forward-slash followed by an optional underscore.
[a-zA-Z0-9]* Any letter or number - Matches zero or more.
<(?:[a-zA-Z]|C[uv]?)> Mandatory <> pair containing one letter or the capital letter C followed by a lowercase u or v.
[a-zA-Z0-9]* Any letter or number - Matches zero or more.
_?\/? An optional underscore followed by an optional forward-slash.
) End of group1.
: Matches a colon character literally.
([a-zA-Z0-9]+|\*) Group 2 - containing one or more numbers or letters or a single * character.
(?=;|$) A positive Lookahead to make sure the string is either followed by a semicolon or is at the end.
Did you mean this?
/^(?:(^|\s*;\s*)(?:\/_|_)?[a-z]*<[a-z]+>[a-z]*_?\/?:(?:[a-z0-9]+|\*)(?=;))+;$/i
We start with a case-insensitive expression /.../i to keep it more readable. You have to rewrite it to a case-sensitive expression if you only want to allow uppercase at the beginning of a word.
^ means the begin of the string. $ means the end of the string.
The whole string ends with ';' after multiple repeatitions of the inner expression (?:...)+ where + means 1 or more ocurrences. ;$ at the end includes the last semicolon into the result. It is not necessary for a test only, since the look-ahead already does the job.
(^|\s*;\s*) every part is at the begin of the string or after a semicolon surrounded by arbitrary whitespaces including linefeed. Use \n if you do not want to allow spaces and tabs.
(?:...|...) is a non-captured alternative. ? after a character or group is the quantifier 0/1 - none or once.
So (?:\/_|_)? means '/', '' or nothing. Use \/?_? if you do want to allow strings starting with a single slash as well.
[a-z]*<[a-z]+>[a-z]* 0 or more letters followed by <...> with at least one letter inside and again followed by 0 or more letters.
_?\/?: optional '_', optional '/', mandatory : in this sequence.
(?:[a-z0-9]+|\*) The part after the colon contains letters and numbers or the asterisk.
(?=;) Look-ahead: Every group must be followed by a semicolon. Look-ahead conditions do not move the search position.

Regular expression : match either of two conditions?

Hi I don't know much about regular expression. But I need it in form validation using angularJs.
Below is the requirement
The input box should accept only if either
(1) first 2 letters alpha + 6 numeric
or
(2) 8 numeric
Below are some correct Inputs :-
(1)SH123456
(2)12345678
(3)sd456565
I tried data-ng-pattern="/(^([a-zA-Z]){2}([0-9]){6})|([0-9]*)?$/" , Its working fine for both the above condition but still it is accepting strings like S2D3E4F5 and may be many other combination as well.
What I am doing wrong I am not able to find it out.
Any help is appreciable !!!
Thanks
In your regex, the two alternative branches are anchored separately:
(^([a-zA-Z]){2}([0-9]){6}) - 2 letters and 6 digits at the start of the string
| - or
([0-9]*)?$ - optional zero or more digits at the end of the string
You need to adjust the boundaries of the group:
data-ng-pattern="/^([a-zA-Z]{2}[0-9]{6}|[0-9]{8})?$/"
^ ^^^^
See the regex demo.
Now, the pattern will match:
^ - start of string
( - start of the grouping:
[a-zA-Z]{2}[0-9]{6} - 2 letters and 6 digits
| - or
[0-9]{8} - 8 digits
)? - end of the grouping and ? quantifier makes it match 1 or 0 times (optional)
$ - end of string.
You can try this DEMO LINK HERE
^(([a-zA-Z]{2}|[0-9]{2})[0-9]{6})?$
It will accept:
ab123456
12345678
aa441236
aw222222

Need to understand some regular expression [duplicate]

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 8 years ago.
I have a regular expression in a code(written by someone else), I am trying to understand what that expression means.
var decimal = /^\d[0,1]+(\.\d[1,4])?$/;
Can anyone explain to me what it does...
In order:
^ - Match the beginning of the input
\d - A digit (0-9)
[0,1]+ - One or more occurrences of the characters 0, ,, or 1 —but see note below, this is probably not what the author meant to do
( - The beginning of a capture group
\. - A literal . (without the backslash, it would mean something special)
\d - A digit
[1,4] - Exactly one of the characters 1, ,, or 4 —but see note below, this is probably not what the author meant to do
) - The end of the capture group
? - Inidicates that the entire capture gruop is optional (zero or once)
$ - Match the end of the input
Re the [0,1]+ and [1,4], the expression was probably supposed to have {0,1} and {1,4} instead, which mean:
{0,1} - match what came before either zero times or once (note that you have to remove the + that was after the [0,1])
{1,4} - match what came before 1, 2, 3, or 4 times
Here's an explanation on regex101.com
If we speculate that they probably meant this
/^\d{0,1}(\.\d{1,4})?$/
...then in prose it means: Match any number that may or may not have one leading digit, and then may or may not have a decimal point followed by one to four digits. But it's still got issues, not least that the string "" matches it, and (depending on what you're doing) you probably want to support values equal to or greater than 2, which that expression doesn't.
Basically: If it's meant to validate a decimal, throw it away, and search for something that does a better job, such as this if you really want at most four digits of precision and you want to capture the fractional portion (as your original does):
/^(?:0|[1-9]\d*)(\.\d{1,4})?$/
If you want to allow any level of precision:
/^(?:0|[1-9]\d*)(\.\d+)?$/
If you don't need the capture group:
/^(?:0|[1-9]\d*)(?:\.\d{1,4})?$/ // Only allow 1-4 digits of precision
/^(?:0|[1-9]\d*)(?:\.\d+)?$/ // Allow any number of digits of precision
That last is probably what I'd go with. Note that it doesn't allow leading zeros you wouldn't normally write (e.g., it disallows 02.345). If you want to allow them, then just /^\d*(?:\.\d+)?$/.
The crucial parts:
^: Beginning of input
\d: A digit
[0,1]+: One or more occurences of 0 or 1 or ,
(\.\d[1,4])?: An optional capture group, containing: a . literal, a digit, and a 1 or 4 or ,
$: End of input
The full story can be found here.
So some allowed input is:
80.94
41111111.44
4,,,1.44
30

business phone regex containing if-else expression

I am trying to write business phone number regex in javascript, my requirements are:
It should contain only digits,dashes and whitespaces
It should not end with - but can end with whitespaces
There should be only 1 - between two groups
It should match numbers with and without - like 1, 123, 678-78
I have tried following regex but it fails for 123-- as it is invalid one anybody please suggest me something
/^([ ]*[0-9]+[-]?[0-9 ]*?([-])[ ]*[0-9]+[ ]*|[0-9 ]*[ ]*)+$/.test('123--2')
Try this
/^[0-9]+(-[0-9\s]+)*$/
I don't know if you still need an answer to this, but this works for your requirements:
/^(?!.+-\s*$)\s*((?:\d+\s*-?\s*)+)$/
Explanation:
^ start of string
(?!.+-\s*$) disallow - (or - followed by whitespace) at the end of the string
\s* optional leading spaces
( start capturing
(?:\d+\s*-?\s*)+ one or more groups of the following:
one or more digits,
possibly followed by whitespace,
possibly followed by a single hyphen,
possibly followed by more whitespace
) stop capturing
$ end of the string
Demo

Categories

Resources