Regex for validate a number with some criteria - php

I need to validate a number with those criterias :
Can be float or integer
Scale 4
Precision 2
I tried like this :
pattern="/^[-+]?[0-9]\d*(\.\d+)?$/i",
Some examples :
valid : 2; -1; 0.4; 0.12; 1928; 1827.78; -182.4
invalid : 10000; 0.345; 89374.5;
Thx in advance.

You may use
'/^[-+]?(?:[1-9]\d{0,3}|0)(?:\.\d{1,2})?$/'
See the regex demo.
Details
^ - start of string
[-+]? - either - or +
(?:[1-9]\d{0,3}|0) - a non-capturing group matching either
[1-9]\d{0,3} - a digit from 1 to 9 (non-zero) and any 0 to 3 digits
| - or
0 - a zero
(?:\.\d{1,2})? - an optional non-capturing group matching 1 or 0 occurrences of
\. - a dot
\d{1,2} - 1 or 2 digits
$ - end of string.

Related

Validate Australian DVA numbers (which may have variable length)

I'm doing validation on Australian DVA numbers, the rules are:
String length should be 8 or 9
First char should be N, V, Q, W, S or T
The next part should be letters or space and can have up to 3 characters
Next part should be number and can have up to 6 number
If the string length is 9 then last char is a letter, if 8 then it must be a number // This is the tricky part
Here is my current attempt and it's working fine:
if (strlen($value) == 9 && preg_match("/^[NVQWST][A-Z\s]{1,3}[0-9]{1,6}[A-Z]$/", $value)) {
return true;
}
if (strlen($value) == 8 && preg_match("/^[NVQWST][A-Z\s]{1,3}[0-9]{1,6}$/", $value)) {
return true;
}
return false;
My question: Is there any way that I can combine these conditions in 1 regex check?
You can use
^(?=.{8,9}$)[NVQWST][A-Z\s]{1,3}[0-9]{1,6}(?:(?<=^.{8})[A-Z])?$
See the regex demo.
Details
^ - start of a string
(?=.{8,9}$) - the string should contain 8 or 9 chars (other than line break chars, but the pattern won't match them)
[NVQWST] - N, V, Q, W, S or T
[A-Z\s]{1,3} - one, two or three uppercase letters or whitespace
[0-9]{1,6} - one to six digits
(?:(?<=^.{8})[A-Z])? - an optional occurrence of an uppercase ASCII letter if it is the ninth character in a string
$ - end of string.
Based on rules and details pulled from these links:
https://www.ppaonline.com.au/wp-content/uploads/2019/05/DVA-number-format-factsheet.pdf
https://meteor.aihw.gov.au/content/339127
I've crafted a comprehensive and strict regex to validate Australian DVA numbers.
$regex = <<<REGEX
/
^
([NVQWST])
(?|
([ ANPVX])(\d{1,6})
|(
BG
|CN
|ET
|F[RW]
|G[RW]
|I[QTV]
|JA
|K[MO]
|MO
|N[FGKX]
|P[KOX]
|R[DMU]
|S[AELMORS]
|U[BS]
|YU
)(\d{1,5})
|(
(?:A(?:FG|GX|LX|R[GX])
|B(?:A[GL]|CG|G[GKX]|RX|U[GRX])
|C(?:AM|CG|HX|IX|LK|N[KSX]|ON|YP|Z[GX])
|D(?:EG|N[KX])
|E(?:G[GXY]|SX|T[KX])
|F(?:I[JX]|R[GKX])
|G(?:HA|R[EGKX])
|H(?:K[SX]|L[GKX]|UX)
|I(?:DA|ND|SR|T[GKX])
|K(?:OS|SH|UG|YA)
|L(?:AX|BX|XK)
|M(?:A[LRU]|LS|OG|TX|WI)
|N(?:BA|CG|GR|IG|RD|S[MSW]|W[GKX])
|OMG
|P(?:A[DGLMX]|C[AGRV]|H[KSX]|L[GX]|MS|S[MW]|WO)
|QAG
|R(?:DX|U[GX])
|S(?:A[GX]|CG|EG|IN|PG|UD|W[KP]|Y[GRX])
|T(?:H[KS]|R[GK]|ZA)
|U(?:AG|RX|S[GKSX])
|V(?:EX|NS)
|Y(?:EM|GX)
|ZIM
)
)(\d{1,4})
)
([A-Z]?)
$
/x
REGEX;
The first character signifies the state/territory.
N = New South Wales (includes Austalian Capital Territory)
V = Victoria
Q = Queensland
W = Western Australia
S = South Australia (includes Northern Territory)
T = Tasmania
My pattern intentionally uses "branch reset" capture groups so that the match array can be easily used to pad the inner "file number" with leading digits when desired.
Here is a demo with sample DVA strings, a preg_match() call, and zero-padding of the file number to represent full length format.
If your application requires the DVAs to be zero padded to 8 or 9 characters, then this is a tighter pattern to enforce that.
Yes, I did this all on my phone.
No, I didn't type it all out maually.
I scraped the one webpage and used regex to format the content into array syntax for my lookup array.
Then I compacted the war code abbreviations into groups and character classes.

Php regex to validate multiple occurence of input

What's the regex for validating input for this
Below 3 line are valid
PROJ9450
PROJ9400-PROJ9401-PROJ9402 ..... PROJ{n}
PROJ9400_1-PROJ9400_2-PROJ9401_1-PROJ9402_1-PROJ9408 ... PROJ{n}_{n}
Below lines are Invalid strings
PROJ450
PRO1223
PROJ9400a-PROJ9401-PROJ9400-PROJ1929-1-PROJ1929
PROJ9400_1-PROJ9400_2-PROJ9401_1-PROJ9402_1-PROJs453 ... PROJ{n}_{n}
I tried this
if( preg_match('/(PROJ)[0-9]{4}(-|_)?[0-9]+)/', $input) )
{
}
I can split and can validate like something like below , but I want to do this by single regex
foreach(explode('-',$input) as $e)
{
if( !preg_match('/(PROJ)[0-9]{4}(-|_)?[0-9]+)/', $e) )
{
return 'Invalid Input';
}
}
Input can be just prefixed by PROJ and 4 digit number
PROJ9450
OR
Input can be prefixed by PROJ and 4 digit number - prefixed by PROJ and
4 digit number like this upto n
PROJ9400-PROJ9401-PROJ9402 ..... PROJ{n}
OR
Input can be prefixed by PROJ and 4 digit number undescore digit -
prefixed by PROJ and 4 digit number underscore digit like this upto
n
PROJ9400_1-PROJ9400_2-PROJ9401_1-PROJ9402_1 ... PROJ{n}_{n}
You need to match the block starting with PROJ and followed with 4 digits (that are optionally followed with - or _ and 1+ digits) repeatedly.
Use
/^(PROJ[0-9]{4}(?:[-_][0-9]+)?)(?:-(?1))*$/
See the regex demo
Details:
^ - start of string anchor
(PROJ[0-9]{4}(?:[-_][0-9]+)?) - Group 1 (that will be later recursed with (?1) recursion construct) capturing:
PROJ - a literal char sequence
[0-9]{4} - 4 digits
(?:[-_][0-9]+)? - an optional (1 or 0 occurrences) of
[-_] - a character class matching - or _
[0-9]+ - 1 or more digits
(?:-(?1))* - zero or more occurrences of - followed with Group 1 subpattern up to...
$ - end of string (better replace it with \z anchor that matches the very end of the string).

Get all matched groups PREG PHP flavor

Pattern : '/x(?: (\d))+/i'
String : x 1 2 3 4 5
Returned : 1 Match Position[11-13] '5'
I want to catch all possible repetitions, or does it return 1 result per group?
I want the following :
Desired Output:
MATCH 1
1. [4-5] `1`
2. [6-7] `2`
3. [8-9] `3`
4. [10-11] `4`
5. [12-13] `5`
Which I was able to achieve just by copy pasting the group, but this is not what I want. I want a dynamic group capturing
Pattern: x(?: (\d))(?: (\d))(?: (\d))(?: (\d))(?: (\d))
You cannot use one group to capture multiple texts and then access them with PCRE. Instead, you can either match the whole substring with \d+(?:\s+\d+)* and then split with space:
$re2 = '~\d+(?:\s+\d+)*~';
if (preg_match($re2, $str, $match2)) {
print_r(preg_split("/\\s+/", $match2[0]));
}
Alternatively, use a \G based regex to return multiple matches:
(?:x|(?!^)\G)\s*\K\d+
See demo
Here is a PHP demo:
$str = "x 1 2 3 4 5";
$re1 = '~(?:x|(?!^)\G)\s*\K\d+~';
preg_match_all($re1, $str, $matches);
var_dump($matches);
Here, (?:x|(?!^)\G) is acting as a leading boundary (match the whitespaces and digits only after x or each successful match). When the digits are encountered, all the characters matched so far are omitted with the \K operator.

Regex validation for North American phone numbers

I am having trouble finding a pattern that would detect the following
909-999-9999
909 999 9999
(909) 999-9999
(909) 999 9999
999 999 9999
9999999999
\A[(]?[0-9]{3}[)]?[ ,-][0-9]{3}[ ,-][0-9]{3}\z
I tried it but it doesn't work for all the instances . I was thinking I can divide the problem by putting each character into an array and then checking it. but then the code would be too long.
You have 4 digits in the last group, and you specify 3 in the regex.
You also need to apply a ? quantifier (1 or 0 occurrence) to the separators since they are optional.
Use
^[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}$
See the demo here
PHP demo:
$re = "/\A[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}\z/";
$strs = array("909-999-9999", "909 999 9999", "(909) 999-9999", "(909) 999 9999", "999 999 9999","9999999999");
$vals = preg_grep($re, $strs);
print_r($vals);
And another one:
$re = "/\A[(]?[0-9]{3}[)]?[ ,-]?[0-9]{3}[ ,-]?[0-9]{4}\z/";
$str = "909-999-9999";
if (preg_match($re, $str, $m)) {
echo "MATCHED!";
}
BTW, optional ? subpatterns perform better than alternations.
Try this regex:
^(?:\(\d{3}\)|\d{3})[- ]?\d{3}[- ]?\d{4}$
Explaining:
^ # from start
(?: # one of
\(\d{3}\) # '(999)' sequence
| # OR
\d{3} # '999' sequence
) #
[- ]? # may exist space or hyphen
\d{3} # three digits
[- ]? # may exist space or hyphen
\d{4} # four digits
$ # end of string
Hope it helps.

preg_match() + 0-1x and digit

I trying to make regexp for telephone numbers. Resp. for this input:
+420123456 -> valid
123456 -> valid
Respective I want regexp where can be one or zero + folowed 1 or n digits
function isTelephoneNumber($telephone) {
preg_match("~^[+]{0,1}[0-9]+$~", $telephone,$match);
return (count($match)>0) ? true:false;
}
also tried
"~^\+{0,1}[0-9]+$~"
"~^[+]?[0-9]+$~"
"~^\+?[0-9]+$~"
But something is wrong with the + character.
Your + is not escaped. This one should do the job :
preg_match("/^\+?\d+$/", $telephone,$match);
\+? => zero or one +
\d+ => one or more digits

Categories