Regex in java to validate a phone number does not work - java

I would like to write a regex which allows to validate a phone number which can be written as follows: 237 698888888 or +237 658888888 or 67883888 ..., in fact the phone number must respect the following condition (+237|237)'Space'(6|2)(5|8|2|3|9|7|6) [0-9] {7}
If the user purposefull to enter a number with prefix the prefix must be 237 or +237 in the case otherwise he decides to enter a number without prefix in this case he must enter a number with 9 digits the first digit must be 6 or 2, the second digit must be between 2,3,5,6,7,8 and 9; And the 7 digits remaining to the choice ie [0-9] {7}. Here is my java code for:
String regex = "(\\+237|237)\" \"(6|2)(2|3|[5-9])[0-9]{7}";
String sPhoneNumber = "237 278889999";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(sPhoneNumber);
if (matcher.matches()) {
Log.e("|==FILTER_NUM==>>","Phone Number Valid");
}
else
{
Log.e("|==FILTER_NUM==>>","Phone Number must be in the form XXX XXXXXXXX");
}
Returns this
E/|==FILTER_NUM==>>: Phone Number must be in the form XXX XXXXXXXX
Please check my code and tell me what's wrong
excuse me for my English :)

Your regex
(\\+237|237)\" \"(6|2)(2|3|[5-9])[0-9]{7}
You are using a space in it. use \\s instead to detect one space.
Also you can simplify this
\\+237|237
To
\\+?(237)
The final regex will look like
(\\+?(237))\\s(6|2)(2|3|[5-9])[0-9]{7}

Your regular expression is searching for literal quote marks ("), which is causing the match to fail. Also, since the prefix is optional, you need to indicate this by following the prefix part of the expression with ?.
The following regular expression should match all your sample phone numbers:
String regex = "(?:\\+?237 )?[26][235-9]\\d{7}";

(\+237|237) [62][^014][0-9]{7} is the expression for more details you can refer javaRegularExpressions. This is the online test of the expression above code test.
for space just use space it will match space too.

Related

minimum number in a string should be 1 regex validation?

I have a String which I need to match. Meaning it should only contains a number followed by space or just a number and minimum number should be 1 always. For ex:
3 1 2
1 p 3
6 3 2
0 3 2
First and third are valid string and all other are not.
I came up with below regex but I am not sure how can I check for minimum number in that string should be 1 always?
str.matches("(\\d|\\s)+")
Regex used from here
Just replace \\d with [1-9].
\\d is just a shorthand for the class [0-9].
This is a better regex though: ([1-9]\\s)*[1-9]$, as it takes care of double digit issues and won't allow space at the end.
Not everything can or should be solved with regular expressions.
You could use a simple expression like
str.matches("((\\d+)\\s)+")
or something alike to simply check that your input line contains only groups of digits followed by one or more spaces.
If that matches, you split along the spaces and for each group of digits you turn it into a number and validate against the valid range.
I have a gut feeling that regular expressions are actually not sufficient for the kind of validation you need.
If it should only contains a number followed by space or just a number and minimum number should be 1 and number can also be larger than 10 you might use:
^[1-9]\\d*(?: [1-9]\\d*)*$
Note that if you want to match a space only, instead of using \s which matches more you could just add a space in the pattern.
Explanation
^ Assert the start of the string
[1-9]\\d* Match a number from 1 up
(?: [1-9]\\d*)* Repeat a number from 1 up with a prepended space
$ Assert end of the string
Regex demo
Regex is part of the solution. But I don't think that regex alone can solve your problem.
This is my proposed solution:
private static boolean isValid(String str) {
Pattern pattern = Pattern.compile("[(\\d+)\\s]+");
Matcher matcher = pattern.matcher(str);
return matcher.matches() && Arrays.stream(Arrays.stream(matcher.group().split(" "))
.mapToInt(Integer::parseInt)
.toArray()).min().getAsInt() == 1;
}
Pay attention to the mathing type: matcher.matches() - to check match against the entire input. (don't use matcher.find() - because it will not reject invalid input such as "1 p 2")

Java Regular Expression: matching a customized Hashtag pattern with a lookahead/lookbehind condition

I am currently learning how to write regular expressions in Java by trying to match simple Hashtag pattern. The Hashtags obey the following conditions:
It starts with a hashtag: #
It has to contain at least 1 letter: [a-zA-Z]
It can contain any of the characters from the class [a-zA-Z0-9_]
It cannot be preceded by a character of the class [a-zA-Z0-9_]
Based on this, I thought that the correct regular expression is:
PATTERN = "(?<![a-zA-Z0-9_])#(?=.*[a-zA-Z])[a-zA-Z0-9_]+"
Here I'm using a lookahead (?=.*[a-zA-Z]) to make sure Condition 2 holds and using a lookbehind (?<![a-zA-Z0-9_]) to make sure Condition 4 holds. I'm less certain about ending with a +.
This works on simple test cases but fails on complicated ones such as:
String text = "####THIS_IS_A_HASHTAG; ;#This_1_2...#12_and_this but not #123 or #this# #or#that";
where does not match #THIS_IS_A_HASHTAG, #This_1_2 and 12_and_this
Could someone explain what I'm doing wrong?
This lookahead:
(?=.*[a-zA-Z])
may produce wrong results for the cases when input is like this:
####12345...#12_and_this
by giving you 2 matches #12345 and #12_and_this. Whereas as per your rules only 2nd should be valid match.
To fix this you can use this regex:
(?<![a-zA-Z0-9_])#(?=[0-9_]*[a-zA-Z])[a-zA-Z0-9_]+
Where lookahead (?=[0-9_]*[a-zA-Z]) means assert presence of a letter after # with optional presence of a digit or underscore in between.
Here is a regex demo for you
How about this?
(example here)
String text = "####THIS_IS_A_HASHTAG;;;#This_1_2...#12_and_this ";
String regex = "#[A-Za-z0-9_]+";
Matcher m = Pattern.compile(regex).matcher(text);
while (m.find()) {
System.out.println(m.group());
}
It looks like it meets your criteria as stated:
#THIS_IS_A_HASHTAG
#This_1_2
#12_and_this

Match regex but only replace the first section - Java

I'm trying to take a phone number which can be in the format either +44 or +4 followed by any number of digits or hyphens, and replace the +44 or +4 with +44 or +4 followed by a space.
I believe I need a look around to match the full number but only replace the initial prefix, what I'm trying atm is
^[+]\d[0-9](?:([0-9]+))?
which matches the number (without hyphens) however I thought the lookahead would only match the number and not capture the extra digits however it seems to capture the whole thing.
Can anyone point me in the right direction as to what I've done wrong?
EDIT:
To be clearer my Java code is
Pattern pattern = Pattern.compile("^[+]\\d[0-9](?:([0-9]+))?");
if(pattern.matcher("+441234567890").matches())
String num = pattern.matcher(title).replaceFirst("$0 $1");
Thanks.
If you want to match whole number, but replace only part of it, you should not use positive lookahead, but just gruping, like in:
(^\+\d\d)([\d-]+)?
prefix will be in group 1, and the rest of number in group 2, so to add a space between these parts, just use something like group1 + space + group2.
In your example it should look like this:
Pattern pattern = Pattern.compile("(^\\+\\d\\d)([\\d-]+)?");
if(pattern.matcher("+441234567890").matches()) {
num = pattern.matcher(title).replaceFirst("$1 $2");
}
However this regex will always capture two digits in prefix, if you want to match +44 or +4 you should use:
(^\+(44|4))([\d-]+)?
so if you have more possible prefixes, you need to change this regex also.
You regex didn't work as you expected because (?:([0-9]+))? is a non capturing group, so the fragment matched by this part of regex was not captured, but it was still matched by whole regex. So $0 returned whole regex, and $1 should not return anything.

How to check if only certain characters appear in a String? [duplicate]

This question already has answers here:
Verify if String is hexadecimal
(8 answers)
Closed 8 years ago.
I need user input for a hexadecimal number so as long as their input contains the characters A-F or 0-9 it won't re-prompt them.
This is what I have which runs as long as the inputed string contains A-F and or 0-9, it still runs if you add on other characters which I don't want.
do {
System.out.print("Enter a # in hex: ");
inputHexNum = keyboard.next();
} while(!(inputHexNum.toUpperCase().matches(".*[A-F0-9].*")));
Could you not change your regex to be [A-F0-9]+?
So your code would look like the following:
do {
System.out.print("Enter a # in hex: ");
inputHexNum = keyboard.next();
} while(!(inputHexNum.toUpperCase().matches("[A-F0-9]+")));
As I understand the question, the problem with your current regex is that it allows any character to occur zero or more times, followed by a hex character, followed by any old character zero or more times again. This restricts the entire input to only containing at least one character that consists of the letters A-F (uppercase) and the digits 0-9.
Your regular expression probably doesn't do what you want. .* matches anything at all (empty string up to any number of arbitrary characters). Then you expect a single hex character followed again by anything.
So these would be valid inputs:
--0--
a
JFK
You should either say "I want a string which contains only valid hex digits. Then your condition would be:
while(!(inputHexNum.toUpperCase().matches("[A-F0-9]+")));
or you can check for any illegal characters with the pattern [^A-F0-9]. In this case, you'd need to create a Matcher yourself:
Pattern illegalCharacters = Pattern.compile("[^A-F0-9]");
Matcher matcher;
do {
...
matcher = illegalCharacters.matches(inputHexNum.toUpperCase());
} while( matcher.find() );
The regular expression that you are using matches every string that contains at least one hex digit. Judging from the first paragraph of the question this is exactly what you want. This is because "." matches any character (but possibly not linebreaks), so ".*" matches any (possibly empty) sequence of characters. Thus the regex ".*[A-F0-9].*" means "first, some arbitrary characters, then a hex digit, then some more characters". But from the second paragraph of the question it looks like you want to use the regex "[A-F0-9]+" which means "some hex digits (but at least one, and nothing else)". I assume you are confused about what needs to be done, but actually want the second.

regex to match a recurring pattern

I am trying to write a regex for java that will match the following string:
number,number,number (it could be this simple or it could have a variable number of numbers, but each number has to have a comma after it there will not be any white space though)
here was my attempt:
[[0-9],[0-9]]+
but it seems to match anything with a number in it
You could try something along the lines of ([0-9]+,)*[0-9]+
This will match:
Only one number, e.g.: 7
Two numbers, e.g.: 7,52
Three numbers, e.g.: 7,52,999
etc.
This will not match:
Things with spaces, e.g.: 7, 52
A list ending with a comma, e.g.: 7, 52,
Many other things out of the scope of this problem.
I think this would work
\d+,(\d+,)+
Note that as you want, that will only capture number followed by a comma
I guess you are starting with a String. Why don't you just use String.split(",") ?
^ means the start of a string and $ means the end. If you don't use those, you could match something in the middle (b matched "abc").
The + works on the element before it. b is an element, [0-9] is an element, and so are groups (things wrapped in parenthesis).
So, the regex you want matches:
The start of the string ^
a number [0-9]
any amount of comas flowed by numbers (,[0-9])+
the end of the string $
or, ^[0-9](,[0-9])+$
Try regex as [\d,]* string representation as [\\d,]* e.g. below:
Pattern p4 = Pattern.compile("[\\d,]*");
Matcher m4 = p4.matcher("12,1212,1212ad,v");
System.out.println(m4.find()); //prints true
System.out.println(m4.group());//prints 12,1212,1212
If you want to match minimum one comma (,) and two numbers e.g. 12,1212 then you may want to use regex as (\d+,)+\d+ with string representation as \\d+,)+\\d+. This regex matches a a region with a number minimum one digit followed by one comma(,) followed by minimum one digit number.

Categories