Validate a state via its pincode in Java [duplicate] - java

This question already has answers here:
Why doesn't [01-12] range work as expected?
(7 answers)
Closed 2 years ago.
I need to generate regex to validate state as Tamilnadu based on Pincode validation
Regex which I tried fails at some point
String regex = "^[60-64]{2}{0-9}{4}$";
Ref the Tamil Nadu Pincode info link. It starts with 60-64 as the first two digits, the next 4 digits as 0-9 numbers. It must have six digits.
the code
public boolean isHomeState(String state, String zipcode) {
if (isValidZipCode(zipcode)) {
// ...
}
return true;
}
private boolean isValidZipCode(String zipcode) {
String regex = "^[60-64]{2}{0-9}{4}$";
Pattern p = Pattern.compile(regex);
// If the pin code is empty
// return false
if (zipcode == null) {
return false;
}
Matcher m = p.matcher(zipcode);
return m.matches();
}

Try the following.
Pattern pattern = Pattern.compile("6[0-4]\\d{4}");
In other words, the digit 6 followed by a digit that is either 0 or 1 or 2 or 3 or 4 and ending with exactly four digits.

There are many regex patterns to do it e.g.
6[0-4][0-9]{4} which means 6 followed by a digit in the range, 0 to 4 which in turn followed by exactly 4 digits.
6[0-4]\d{4} which means 6 followed by a digit in the range, 0 to 4 which in turn followed by exactly 4 digits
6[0-4][0-9][0-9][0-9][0-9] which means 6 followed by a digit in the range, 0 to 4 which in turn followed by exactly 4 digits
However, let's analyze your regex, [60-64]{2}[0-9]{4} which will help you understand the problem better.
The regex, [60-64] means only one of the following:
6
A digit in the range 0 to 6
4
And [60-64]{2} means the above repeated exactly two times i.e. it will match with a combination of 2 digits in the range, 0 to 6 e.g. 00, 60, 34, 01, 10, 11 etc.
As a result, the regex, [60-64]{2}[0-9]{4} will match with first 2 digits consisting of digits in the range, 0 to 6 and next 4 digits consisting of digits in the range, 0 to 9 e.g.
012345
123856
234569
101010
202020
303030
404040
505050
606060
111111
222222
333333
which is not something you expect.

Related

Regex not matching all numbers with delimiters

Need a single combined regex for the following pattern:
Prefix: 2221-2720 , Length: 16
Prefix: 51-55 , Length: 16
where the delimiters b/w digits can be either space ( ), minus sign (-), period (.), backslash (\), equals (=). The condition being that more than one delimiter (same or different type) can't occur more than once b/w any two digits.
Valid number - 230.293.217.952.148.4
Valid number - 230.293 217-952.148.4
Invalid number - 230..293.217.952.148.4
Invalid number - 230.293.-217. 952.148.4
A valid input is one where you have 16 digits separated by any/no delimiters as long as there are no two delimiters adjacent to each other.
Have come up with the following regex:
(2[\s=\\.-]*2[\s=\\.-]*2[\s=\\.-]*[1-9][\s=\\.-]*|2[\s=\\.-]*2[\s=\\.-]*[3-9][\s=\\.-]*[0-9][\s=\\.-]*|2[\s=\\.-]*[3-6][\s=\\.-]*[0-9](?:[\s=\\.-]*[0-9]){1}|2[\s=\\.-]*7[\s=\\.-]*[01][\s=\\.-]*[0-9][\s=\\.-]*|2[\s=\\.-]*7[\s=\\.-]*2[\s=\\.-]*0[\s=\\.-]*)[0-9](?:[\s=\\.-]*[0-9]){11}|(5[\s=\\.-]*[1-5][\s=\\.-]*)[0-9](?:[\s=\\.-]*[0-9]){13}
It does not match certain patterns. For example:
2 3 0 2 9 3 2 1 7 9 5 2 1 4 8 4
23-02-93-21-79-52-14-84
2 3 0 3 4 5 8 0 9 4 9 3 0 8 2 3
For the same numbers, it matches (as expected) the following patterns:
2302932179521484
230.293.217.952.148.4
2303458094930823
230.345.809.493.082.3
230-345-809-493-082-3
There seems to be an issue with delimiters. Kindly let me know what is wrong with my regex.
For this rule
A valid input is one where you have 16 digits separated by any/no
delimiters as long as there are no two delimiters adjacent to each
other
Prefix: 2221-2720 , Length: 16
Prefix: 51-55 , Length: 16
2221 can also be written as 2.2.-2.1
For these rules, it might be easier to write a pattern with 2 capture groups to match the whole string.
Then using some Java code, you can check the value of the capture groups for the ranges.
^((\d[ =\\.-]?\d)[ =\\.-]?\d[ =\\.-]?\d)(?:[ =\\.-]?\d){12}$
The pattern matches:
^ Start of string
( Capture group 1
(\d[ =\\.-]?\d) Capture group 2 Match 2 digits with an optional char = \ . -
[ =\\.-]?\d[ =\\.-]?\d Match 2 times optionally 1 of the listed chars and a single digit
) close group 1
(?:[ =\\.-]?\d){12} Repeat 12 times matching one of the characters and a single digit
$ End of string
Regex demo | Java demo
For example
String strings[] = {
"2221.7.952.148.412.32",
"230.293.217.952.148.4",
"5511111111111111",
"130.293 217-952.148.4",
"30..293.217.952.148.4",
"5..5",
".5.5."
};
String regex = "^((\\d[ =\\\\.-]?\\d)[ =\\\\.-]?\\d[ =\\\\.-]?\\d)(?:[ =\\\\.-]?\\d){12}$";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
for (String s : strings) {
Matcher matcher = pattern.matcher(s);
if (matcher.find()) {
int grp1 = Integer.parseInt(matcher.group(1).replaceAll("\\D+", ""));
int grp2 = Integer.parseInt(matcher.group(2).replaceAll("\\D+", ""));
if ((grp1 >= 2221 && grp1 <= 2720) || (grp2 >=51 && grp2 <= 55)) {
System.out.println("Match for " + matcher.group());
}
}
}
Output
Match for 2221.7.952.148.412.32
Match for 230.293.217.952.148.4
Match for 5511111111111111

Why does this regex fails to check accurately?

I have the following regex method which does the matches in 3 stages for a given string. But for some reason the Regex fails to check some of the things. As per whatever knowledge I have gained by working they seem to be correct. Can someone please correct me what am I doing wrong here?
I have the following code:
public class App {
public static void main(String[] args) {
String identifier = "urn:abc:de:xyz:234567.1890123";
if (identifier.matches("^urn:abc:de:xyz:.*")) {
System.out.println("Match ONE");
if (identifier.matches("^urn:abc:de:xyz:[0-9]{6,12}.[0-9]{1,7}.*")) {
System.out.println("Match TWO");
if (identifier.matches("^urn:abc:de:xyz:[0-9]{6,12}.[a-zA-Z0-9.-_]{1,20}$")) {
System.out.println("Match Three");
}
}
}
}
}
Ideally, this code should generate the output
Match ONE
Match TWO
Match Three
Only when the identifier = "urn:abc:de:xyz:234567.1890123.abd12" but it provides the same output event if the identifier does not match the regex such as for the following inputs:
"urn:abc:de:xyz:234567.1890123"
"urn:abc:de:xyz:234567.1890ANC"
"urn:abc:de:xyz:234567.1890123"
"urn:abc:de:xyz:234567.1890ACB.123"
I am not understanding why is it allowing the Alphanumeric characters after the . and also it does not care about the characters after the second ..
I would like my Regex to check that the string has the following format:
String starts with urn:abc:de:xyz:
Then it has the numbers [0-9] which range from 6 to 12 (234567).
Then it has the decimal point .
Then it has the numbers [0-9] which range from 1 to 7 (1890123)
Then it has the decimal point ..
Finally it has the alphanumeric character and spcial character which range from 1 to 20 (ABC123.-_12).
This is an valid string for my regex: urn:abc:de:xyz:234567.1890123.ABC123.-_12
This is an invalid string for my regex as it misses the elements from point 6:
urn:abc:de:xyz:234567.1890123
This is also an invalid string for my regex as it misses the elements from point 4 (it has ABC instead of decimal numbers).
urn:abc:de:xyz:234567.1890ABC.ABC123.-_12
This part of the regex:
[0-9]{6,12}.[0-9]{1,7} matches 6 to 12 digits followed by any character followed by 1 to 7 digits
To match a dot, it needs to be escaped. Try this:
^urn:abc:de:xyz:[0-9]{6,12}\.[0-9]{1,7}\.[a-zA-Z0-9\-_]{1,20}$
This will match with any number of dot alphanum at the end of the string as your examples:
^urn:abc:de:xyz:\d{6,12}\.\d{1,7}(?:\.[\w-]{1,20})+$
Demo & explanation

Java check Phone number and matches

i want to check below phone number with matches, phone number conditions :
start with 0 or 9
content must be between 0 and 9
phone number must be 10 character
I tried:
String mobile_number = "9371236569";
if(!TextUtils.isEmpty(mobile_number) &&
mobile_number.matches("^[0][9][0-9]{10}$")) {
}
For number 9371236569 dont work my code and return false,
[ ] Matches any single character in brackets except range with -.
mobile_number.matches("^[09][0-9]{9}$")
^[09] start with eighter 0 or 9.
[0-9]{9} rest 9 digits raging from 0-9.
Use this regex:
"^(0|9)[0-9]{9}$"
Explanation:
^ match beginning of the string
(0|9) match one digit either a 0 or a 9
[0-9]{9} match 9 digits in the range of 0-9
$ match end of the string
public static boolean validateMobile(String moblieNumber) {
boolean check;
Pattern p;
Matcher m;
String MobilePattern = "[0-9]{10}";
p = Pattern.compile(MobilePattern);
m = p.matcher(moblieNumber);
check = m.matches();
return check;
}

Trying to understand this Regex code [duplicate]

This question already has an answer here:
SCJP6 regex issue
(1 answer)
Closed 7 years ago.
I have the following code. As far as I can see, the program should print 0123445. Instead, it prints 01234456.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Regex2 {
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d*");
Matcher m = p.matcher("ab34ef");
boolean b = false;
while(b=m.find()){
System.out.print(m.start() + m.group());
}
System.out.println();
}
}
I think the following should happen-
Since the search pattern is for a \d*,
It finds a hit at position 0, but since the hit is not a digit, it just prints 0
It finds a hit at position 1, but again, not a digit, prints 0
Finds a hit at position 2 and since we are looking for \d*, the hit is 34, and so it prints 234.
Moves to position 4, finds a hit, but since hit is not a digit, it just prints 4.
Moves to position 5, finds a hit, but since hit is not a digit, it just prints 5.
At this point, as far as I can see, it should be done. But for some reason, the program also returns a 6.
Much appreciate it if someone can explain.
The \d* matches zero(!) or more digits, that's why it returns an empty string as a match at 0 and 1, it the matches 34 at position 2 and an empty string again at position 4 and 5. At that point what is left to match against is an empty string. And this empty string also matches \d* (because an empty string contains zero digits), that's why there is another match at position 6.
To contrast this try using \d+ (which matches one or more digits) as the pattern and see what happens then.

Understanding regular expression output [duplicate]

This question already has an answer here:
SCJP6 regex issue
(1 answer)
Closed 7 years ago.
I need help to understand the output of the code below. I am unable to figure out the output for System.out.print(m.start() + m.group());. Please can someone explain it to me?
import java.util.regex.*;
class Regex2 {
public static void main(String[] args) {
Pattern p = Pattern.compile("\\d*");
Matcher m = p.matcher("ab34ef");
boolean b = false;
while(b = m.find()) {
System.out.println(m.start() + m.group());
}
}
}
Output is:
0
1
234
4
5
6
Note that if I put System.out.println(m.start() );, output is:
0
1
2
4
5
6
Because you have included a * character, your pattern will match empty strings as well. When I change your code as I suggested in the comments, I get the following output:
0 ()
1 ()
2 (34)
4 ()
5 ()
6 ()
So you have a large number of empty matches (matching each location in the string) with the exception of 34, which matches the string of digits. Use \\d+ if you want to match digits without also matching empty strings..
You used this regex - \d* - which basically means zero or more digits. Mind the zero!
So this pattern will match any group of digits, e.g. 34 plus any other position in the string, where the matched sequence will be the empty string.
So, you will have 6 matches, starting at indices 0,1,2,4,5,6. For match starting at index 2, the matched sequence is 34, while for the remaining ones, the match will be the empty string.
If you want to find only digits, you might want to use this pattern: \d+
d* - match zero or more digits in the expresion.
expresion ab34ef and his corresponding indices 012345
On the zero index there is no match so start() prints 0 and group() prints nothing, then on the first index 1 and nothing, on the second we find match so it prints 2 and 34. Next it will print 4 and nothing and so on.
Another example:
Pattern pattern = Pattern.compile("\\d\\d");
Matcher matcher = pattern.matcher("123ddc2ab23");
while(matcher.find()) {
System.out.println("start:" + matcher.start() + " end:" + matcher.end() + " group:" + matcher.group() + ";");
}
which will println:
start:0 end:2 group:12;
start:9 end:11 group:23;
You will find more information in the tutorial

Categories