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.
Related
I want to allow lowercase characters and numbers in username field.
But with following conditions...
Only numbers as username NOT allowed (e.g. only mobile number)
Only lowercase characters allowed (e.g. without any number in username)
Lowercase characters + numbers allowed (e.g. combination of lowercase and numbers)
Minimum length 8 characters required
Maximum length 20 characters allowed
What php regex will do it ?
I tried with following, but it forces lowercase + numbers. Only lowercase username not allowing.
$username_pattern = '/^(?=.*[a-z])(?=.*[a-z])(?=.*\d)[a-z0-9]{8,20}$/';
I want only lowercase and/or lowercase+numbers ( min 8 and max 20 ) in username
Help appreciated.
You can simplify it to not allowing only digits
^(?!\d*$)[a-z0-9]{8,20}$
Explanation
^ Start of string
(?!\d*$) Negative lookahead, assert not only digits till end of string
[a-z0-9]{8,20} Match 8-20 times a char a-z or a digit 0-9
$ End of string
Regex demo | Php demo
$username_pattern = '/^(?!\d*$)[a-z0-9]{8,20}$/';
$userNames = [
"1a3b5678",
"1a3b5678abcd",
"12345678",
"1a3b5678abcddddddddddddddddddddddddddddddd",
"1a3B5678",
"a1"
];
foreach ($userNames as $userName) {
if (preg_match($username_pattern, $userName)) {
echo "Match - $userName" . PHP_EOL;
} else {
echo "No match - $userName" . PHP_EOL;
}
}
Output
Match - 1a3b5678
Match - 1a3b5678abcd
No match - 12345678
No match - 1a3b5678abcddddddddddddddddddddddddddddddd
No match - 1a3B5678
No match - a1
I need a regex to find any string that matches the format: a '+' or a '-', followed by a number or a letter, followed by a colon ':'.
Example:
"+2: Each player discards a card.\n−X: Return target nonlegendary creature card with converted mana cost X from your graveyard to the battlefield.\n−8: You get an emblem with \"Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step.\"
Should match "+2:", "-X:" and "-8:".
I've done /[0-9a-z]:/i but I can't match the plus and minus.
Thanks in advance guys.
You may use
$re = '/[−+-]?[0-9a-z]:/iu';
$str = '+2: Each player discards a card.\\n−X: Return target nonlegendary creature card with converted mana cost X from your graveyard to the battlefield.\\n−8: You get an emblem with \\"Whenever a creature dies, return it to the battlefield under your control at the beginning of the next end step.';
if (preg_match_all($re, $str, $matches)) {
print_r($matches[0]);
}
See the PHP demo
The [−+-]? part matches an optional −, - or + chars.
If you want to support any other "minus" looking chars, use
$re = '/[−+\p{Pd}]?[0-9a-z]:/iu';
The \p{Pd} matches dash punctuation chars, but not the − char, unfortunately.
i have too many strings are not in a general pattern. All has digits but i need have to get which contains 11 character "numbers only" in this string. For example:
"John Doe 12345 12345678910 123456789123456 12:22:54 Transfer from atm"
"John Doe 12:22:54 123456789123456 Transfer from atm 12345678910"
for these string I have to get "12345678910" only. So there is no general pattern. And string can contain numbers moren than 11 character. So I have get only 11 character numbers! How can I do that in php?
You can use preg_match to get you desired 11 digits :
<?php
$string = '"John Doe No:12345 Id:12345678910 Key:123456789123456 12:22:54 Transfer from atm"';
if(preg_match('#(\D|\b)([\d]{11})(\D|\b)#', $string, $matches) != false){
print_r($matches[2]);
}
Output
12345678910
Regular Expression Explained :
(\D|\b): \D means non-numeric character, \b means word boundary. | is OR operator. so this group will match either non-numeric character or word boundary. (start of string, space)
([\d]{11}): \d means numeric digit. {11} suggests we match digit only 11 times, no more no less. This is the main group we need to capture.
(\D|\b): Repeat of first group just to support end of string or word boundary.
$matches[2] will always hold the desired 11 digit.
From your question, You need to extract 11 digit number.
Pass the string though a regex and extract all sub-strings that are numeric,
Loop through the matches and get the number whose length is 11 characters.
$str = "John Doe 12345 12345678910 123456789123456 12:22:54 Transfer from atm";
preg_match_all('/\d+/', $str, $matches);
$_value= null;
foreach($matches[0] as $value){
if(strlen($value)==11)
$_value = $value;
}
print_r($_value);
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).
Consider example:
$mystring = "us100ch121jp23uk12";
I) I want to change value of jp by adding +1 so that makes the string into
us100ch121jp24uk12
suppose if
II) Is there a way to seperate the numeric part and alphabetic part in the above string into:
[us , 100]
[ch,121]
[jp,24]
[us,12]
my code:
$string = "us100ch121jp23uk12";
$search_for = "us";
$pairs = explode("[]", $string); // I dont know the parameters.
foreach ($pairs as $index=>$pair)
{
$numbers = explode(',',$pair);
if ($numbers[0] == $search_for){
$numbers[1] += 1; // 23 + 1 = 24
$pairs[index] = implode(',',$numbers); //push them back
break;
}
}
$new_string = implode('|',$pairs);
using Evan sir's suggestions
$mystring = "us100ch121jp22uk12";
preg_match_all("/([A-z]+)(\d+)/", $mystring, $output);
//echo $output[0][4];
foreach($output[0] as $key=>$value) {
// echo "[".$value."]";
echo "[".substr($value, 0, 2).",".substr($value, 2, strlen($value) - 2)."]"."<br>";
}
If you use preg_match_all("/([A-z]+)(\d+)/", $string, $output);, it will return an array to $output that contains three arrays. The first array will be country number strings (eg 'us100'). The second will contain country strings (eg 'us'). The third will contain the numbers (eg '100').
Since the second and third arrays will have matching indexes ($output[1][0] will be 'us' and $output[2][0] will be '100'), you could just cycle through those and do whatever you'd like to them.
Here is more information about using regular expressions in PHP. The site also contains information about regular expressions in general, which are a useful tool for any programmer!
You can do it using regular expressions in PHP. See tutorial:
http://w3school.in/w3schools-php-tutorial/php-regular-expression/
Function Description
ereg_replace() The ereg_replace() function finds for string specified by pattern and replaces pattern with replacement if found.
eregi_replace() The eregi_replace() function works similar to ereg_replace(), except that the search for pattern in string is not case sensitive.
preg_replace() The preg_replace() function works similar to ereg_replace(), except that regular expressions can be used in the pattern and replacement input parameters.
preg_match() The preg_match() function finds string of a pattern and returns true if pattern matches false otherwise.
Expression Description
[0-9] It matches any decimal digit from 0 through 9.
[a-z] It matches any character from lowercase a through lowercase z.
[A-Z] It matches any character from uppercase A through uppercase Z.
[a-Z] It matches any character from lowercase a through uppercase Z.
p+ It matches any string containing at least one p.
p* It matches any string containing zero or more p’s.
p? It matches any string containing zero or more p’s. This is just an alternative way to use p*.
p{N} It matches any string containing a sequence of N p’s
p{2,3} It matches any string containing a sequence of two or three p’s.
p{2, } It matches any string containing a sequence of at least two p’s.
p$ It matches any string with p at the end of it.
^p It matches any string with p at the beginning of it.
[^a-zA-Z] It matches any string not containing any of the characters ranging from a through z and A through Z.
p.p It matches any string containing p, followed by any character, in turn followed by another p.
^.{2}$ It matches any string containing exactly two characters.
<b>(.*)</b> It matches any string enclosed within <b> and </b>.
p(hp)* It matches any string containing a p followed by zero or more instances of the sequence hp.
you also can use JavaScript:
http://www.w3schools.com/jsref/jsref_obj_regexp.asp