Validate a gsheet/excel relative range string using js regex - javascript

I want to validate a range using javascript
Any range that has $ symbol must say invalid
Any range string that has symbols other than : must say invalid
Accpetable characters are capital or small alphabets and 0-9 numbers
Some of the expected results
A0 // invalid range begins with 1
ZZ12 // valid
ZZ12: // invalid incorrectly terminated
:A11 // invalid incorrectly started
:1 // invalid incorrectly started
:A // invalid incorrectly started
A1 // valid
B1 // valid
A2 // valid
C:F // valid
A10:B10 // valid
A:B10 // valid
A10:B // valid
A:B // valid
10:10 // valid
AA1 // valid
AAA1 // valid
B9:B10 // valid
A // invalid incomplete range string
1 // invalid incomplete range string
B // invalid incomplete range string
20 // invalid only a number not allowed
# // invalid symbols not allowed
## // invalid symbols not allowed
I have tried with
["A0","ZZ12","ZZ12:",":A11",":1",":A","A1","B1","A2","C:F","A10:B10","A:B10","A10:B","A:B","10:10","AA1","AAA1","B9:B10","A","1","B","20","#","##"]
.map(zz=>{return zz + "--->" + /^[A-Z]?[0-9]?:[A-Z]?[0-9]?$/.test(zz)})

This solution should address all your requirements, also for non-zero numbers:
const regex = /^(?:[A-Z]+[1-9][0-9]*|[A-Z]+(?:[1-9][0-9]*)?:[A-Z]+(?:[1-9][0-9]*)?|[1-9][0-9]*:[1-9][0-9]*)$/;
["A0","ZZ12","ZZ12:",":A11",":1",":A","A1","B1","A2","C:F","A10:B10","A:B10","A10:B","A:B","10:10","1:999","0:1","AA1","AAA1","B9:B10","A","1","B","20","#","##"
].map(str => {
//let valid = regex.test(str);
let valid = str.match(regex);
console.log(str, '==>', valid ? 'ok' : 'invalid');
});
Explanation of regex:
^(?: -- start of string and non-capture group start
[A-Z]+[1-9][0-9]* -- 1+ letters, number starting from 1
| -- logical or
[A-Z]+(?:[1-9][0-9]*)?:[A-Z]+(?:[1-9][0-9]*)? -- 1+ letters, optional number starting from 1, :, 1+ letters, optional number starting from 1
| -- logical or
[1-9][0-9]*:[1-9][0-9]* -- 1+ letters, number starting from 1, :, 1+ letters, number starting from 1
)$ -- end of non-capture group and string

With your shown samples please try following regex and JS code. Here is the Online Demo for used regex.
const regex = /^(?:[a-zA-Z]+\d*:[a-zA-Z]+\d*|[a-zA-Z]+[1-9]+\d*|\d+:\d+)$/;
[
"A0",
"ZZ12",
"ZZ12:",
":A11",
":1",
":A",
"A1",
"B1",
"A2",
"C:F",
"A10:B10",
"A:B10",
"A10:B",
"A:B",
"10:10",
"AA1",
"AAA1",
"B9:B10",
"A",
"1",
"B",
"20",
"#",
"##",
"$"
].forEach(element =>
console.log(`${element} ----> ${regex.test(element)}`)
);
Explanation: Adding detailed explanation for above used regex.
^ ##Checking from starting of value here.
(?: ##Starting one and only non-capturing group here.
[a-zA-Z]+\d*: ##matching 1 or more alphabets followed by 0 or more digits followed by colon.
[a-zA-Z]+\d* ##matching 1 or more alphabets followed by 0 or more digits here.
| ##Putting OR condition here.
[a-zA-Z]+[1-9]+\d* ##Matching 1 or more alphabets followed by 1 or more digits.
| ##Putting OR condition here.
\d+:\d+ ##Matching 1 or more digits followed by colon followed by 1 or more digits.
)$ ##Closing non-capturing group at the end of the value here.

Try this:
^([A-Za-z])\1*(?:[1-9]\d*)*:([A-Za-z])\2*(?:[1-9]\d*)*$|^(?:([A-Za-z])\3*|[1-9]\d*:)[1-9]\d*$
Explanation:
First part ^([A-Za-z])\1*(?:[1-9]\d*)*:([A-Za-z])\2*(?:[1-9]\d*)*$ to match things like C:F, A10:B10, A:B10, A10:B, A:B and B9:B10.
^ start of the line/string.
([A-Za-z]) Group1: [A-Za-z] one letter captured by the first group, and the value inside the first capturing group can be accessed by \1.
\1*, \1 the value inside the first capturing group, * match zero or more of the value inside the first capturing group, for example if the value is A, then things like AAA will be matched.
(?:[1-9]\d*)* non-capturing group, [1-9] one digit from 1 to 9, followed by \d* zero or more digits from 0 to 9, and that group will be repeated between zero or more times.
: a literal colon :.
([A-Za-z]) Group2:[A-Za-z] the same as before with Group1, but now we can access the value inside the second capturing group by \2.
\2* the same as before with \1*, but now the value is the one inside the second capturing group.
(?:[1-9]\d*)* the same as before.
$ the end of the line/string.
| the alternation operator it is like Boolean OR, to match other cases.
Second part ^(?:([A-Za-z])\3*|[1-9]\d*:)[1-9]\d*$ to match things like A1, B1, A2 and 10:10.
^ the start of the line/string.
(?:([A-Za-z])\3*|[1-9]\d*:) non-capturing group contains:
([A-Za-z]) Group3:[A-Za-z] the same as before with Group1 and Group2, but now we can access the value inside the third capturing group by \3.
\3* the same as before with \1* and \2*, but now the value is the one inside the third capturing group.
| the alternation operator it is like Boolean OR, to match other cases.
[1-9]\d*: one digit from 1 to 9, followed by zero or more digits from 0 to 9, followed by a literal :.
[1-9]\d* one digit from 1 to 9, followed by zero or more digits from 0 to 9.
$ the end of the line/string.
See regex demo

Related

regex to accept number in fomat 00.00

In my Angular App I am trying to set validation on input field such as
it should accept only 2 digit number or floating point number with 2 digit after point and before point too
Example
Accepted value
3,
33,
33.3,
33.33
Max value can be 99.99
Not accepting
333
33.333
3.333
333.33
Currently I am using
pattern="[+]?((\d{1,2})+(?:[\.][0-9]{0,2})?|\.[0-9]{0,2})$"
it validate 2 digit after point but failed to validate two digit before point as it accept 333.33 (which is wrong)
I also tried
pattern="[+]?(([0-9])+(?:[\.][0-9]{0,2})?|\.[0-9]{0,2})$"
But same thing happen , it does not validate two digit before point
This pattern (\d{1,2})+ will match 1 - 2 digits and will repeat that one or more times.
A pattern like \.[0-9]{0,2} will also match just a single dot because the digits will match 0 - 2 times.
You could use an anchor to assert the start ^ and the end $ of the string. Match 1 or 2 digits with an optional part that matches a dot and 1 or 2 digits:
^\d{1,2}(?:\.\d{1,2})?$
Regex demo
Explanation
^ Assert the start of the string
\d{1,2} Match a digit 1 or 2 times
(?: Non capturing group
\.\d{1,2} Match a dot literally and 1 or 2 digits
)? Close non capturing group and make it optional
$ Assert the end of the string
If you want to match an optional plus at the beginning, the start of the regex could be^\+?
let pattern = /^\d{1,2}(?:\.\d{1,2})?$/;
let strs = [
"99",
"3",
"33",
"33.3",
"33.33",
"333",
"33.333",
"3.333",
"333.33"
];
strs.forEach((s) => {
console.log(s + " ==> " + pattern.test(s));
});
It seems to me the regular expression can be simplified. Do you really want an optional leading "+"? I've left it out as your examples don't include it, put it back in if you want.
function testValue(){
// Optional leading +
// var re = /^\+?\d{1,2}(\.\d{1,2})?$/;
// No leading +
var re = /^\d{1,2}(\.\d{1,2})?$/;
console.log(re.test(this.value));
}
window.onload = function(){
document.querySelector('input').addEventListener('input',testValue,false);
}
Enter number: <input>

Regular expression that match string without fixed length

i have a strings like this
01084700069811461719010010285322921DA192089940088
01084700088763891719050010BM2120
Those strings are datamatrix string, and i have to split strings in this way
0108470006981146 17190100 102853229 21DA192089940088
0108470008876389 17190500 10BM2120
Each block start with a fixed code and is followed by digits o characters
01 + 14 digits
17 + 6 digits
10 + from 1 to 20 characters
21 + from 1 to 20 characters
I try to make this using regular expression, and for the first two blocks i don't have problems because the length is fixed. I have problems with the third (and/or the fourth) block.
I create this regexp
/^(01\d{14})(?:(17\d{6}))*(?:(10\w*))*(?:(21\w*))*$/
For this string is correct
01084700088763891719050010BM2120
Group 1. 0108470008876389 (ok)
Group 2. 17190500 (ok)
Group 3. 10BM2120 (ok)
but for the other string
01084700069811461719010010285322921DA192089940088
the regexp match
Group 1. 0108470006981146 (ok)
Group 2. 17190100 (ok)
Group 3. 10285322921DA192089940088 (no)
I don't be able to create a regexp that is able to match correctly the third and the fourth block because have not a fixed length of characters and because is possible that in the third block there is the string "21" that is also the start code of the next block.
It's possibile to create a regular expression that match correctly all the parts of the string.
Thanks to all
You may use
^(01\d{14})(17\d{6})?(10\w{1,20})?(21\w{1,20})?$
See the regex demo
Note that you do not have to wrap the capturing groups with non-capturing ones if you plan to quantify them, you may quantify the capturing groups directly.
Also, to make a group optional, it is enough to use ? quantifier, as * matches 0 or more occurrences.
Pattern details
^ - start of string
(01\d{14}) - Group 1: 01 and 24 digits
(17\d{6})? - Group 2 (optional): 17 and 6 digits
(10\w{1,20})? - Group 3 (optional): 10 and 1 to 20 word chars
(21\w{1,20})? - Group 4 (optional): 21 and 1 to 20 word chars
$ - end of string.
Note that to match only alphanumeric chars, you need to replace \w with [^\W_] since \w also matches _.
var inputValue = "01084700088763891719050010BM2120";
var regexpr = /(01\d{14})(17\d{6})(10[A-Za-z0-9]{1,20})(21[A-Za-z0-9]{1,20})/;
inputValue.replace(regexpr, "$1 $2 $3 $4");
The output will be :
"0108470008876389 17190500 10BM 2120"
var inputValue = "01084700069811461719010010285322921DA192089940088";
var regexpr = /(01\d{14})(17\d{6})(10[A-Za-z0-9]{1,20})(21[A-Za-z0-9]{1,20})/;
inputValue.replace(regexpr, "$1 $2 $3 $4");
The output will be :
"0108470006981146 17190100 102853229 21DA192089940088"

“combine” 2 regex with a logic or?

I have two patterns for javascript:
/^[A-z0-9]{10}$/ - string of exactly length of 10 of alphanumeric symbols.
and
/^\d+$/ - any number of at least length of one.
How to make the expression of OR string of 10 or any number?
var pattern = /^([A-z0-9]{10})|(\d+)$/;
doesn't work by some reason. It passes at lest
pattern.test("123kjhkjhkj33f"); // true
which is not number and not of length of 10 for A-z0-9 string.
Note that your ^([A-z0-9]{10})|(\d+)$ pattern matches 10 chars from the A-z0-9 ranges at the start of the string (the ^ only modifies the ([A-z0-9]{10}) part (the first alternative branch), or (|) 1 or more digits at the end of the stirng with (\d+)$ (the $ only modifies the (\d+) branch pattern.
Also note that the A-z is a typo, [A-z] does not only match ASCII letters.
You need to fix it as follows:
var pattern = /^(?:[A-Za-z0-9]{10}|\d+)$/;
or with the i modifier:
var pattern = /^(?:[a-z0-9]{10}|\d+)$/i;
See the regex demo.
Note that grouping is important here: the (?:...|...) makes the anchors apply to each of them appropriately.
Details
^ - start of string
(?: - a non-capturing alternation group:
[A-Za-z0-9]{10} - 10 alphanumeric chars
| - or
\d+ - 1 or more digits
) - end of the grouping construct
$ - end of string

Regex for word and 2 numbers?

I am trying to create a regex on an input string for a name and 2 numbers separated by a comma and another word(words in capital):
PETER 1,2 PARENT //valid
PETER 1,2 //invalid
PETER 1,PARENT //invalid
What would the regex for this be? The numbers range from 0-4.
/^[A-Z]+ [0-4],[0-4] [A-Z]+$/
^ // start match
[A-Z]+ // one or more capital letters
// one space
[0-4] // a number between 0 and 4
, // comma
[0-4] // a number between 0 and 4
// one space
[A-Z]+ // one or more capital letters
$ // end match
Did you even try?
.+\s\d+,\d+\s.+, that means;
1) .+ -> (any character except new line) match one or more
2) \s -> match space
3) \d+ -> (any digit) match one or more
4) , -> match comma
5) match 3, 2 and 1

Regex for phone numbers that check if numbers are not the same and last 7 digits are not same

I am trying to create a regex which matches 7-15 digit number, the number cannot contain all the same digits and Last 7 digits cannot be the same. I have made two regex expressions for number that all numbers cannot be same. The regex which I have made is:
/^(?!(.)\1+$)^(|[0-9]{7,15})$/.
And for Last seven digits cannot be same,the regex which i have made is:
/^(?!.*(\d)\1{6}\b)^[0-9]{0,15}$/.
But the problem is I am not able to make the regex which full fills both the conditions i.e. all the numbers cannot contain all the same digits and Last 7 digits cannot be the same.
Please suggest how this can be done.
It seems you can use alternation operator inside the negative lookahead to check for 2 conditions:
^(?!(\d)\1+$|\d*(\d)\2{6}$)(?:\d{7,15})?$
See the regex demo.
Details:
^ - start of string
(?!(\d)\1+$|\d*(\d)\2{6}$) - the negative lookahead failing the match if all digits are the same from start to end ((\d)\1+$ where (\d) captures a digit into Group 1 and then \1+ matches one or more values captured in Group 1 followed with end of string check with $), or if only the last 7 are the same (see \d*(\d)\2{6}$ where \d* matches 0+ digits, (\d) captures a digit into Group 2 and then \2{6} matches 6 values captured in Group 2 followed with end of string check with $)
(?:\d{7,15})? - an optional group matching 7 to 15 digits (or an empty string, as it's optional)
$ - end of string.

Categories

Resources