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")
Related
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.
I'm trying to create a Regex for a String validator. My String must be exactly 8 characters long, and begin with a letter (lowercase or uppercase) or a number. It can only contain letters (lowercase and uppercase), numbers or whitespaces right after that first character. If a whitespace is found, there can only be whitespaces after it.
For now, I have the match group for the second part : [a-zA-Z0-9]{1,}\s*
I can't find a way to specify that this group is matched only if it has exactly 8 characters. I tried ^([a-zA-Z0-9]{1,}\s*){8}$ but this is not the expected result.
Here are some test cases (with trailing whitespaces).
Valid :
9013
20130
89B
A5000000
Invalid :
9013
20130
90 90
123456789
There probably is a smart regex way to do it but you could also first check the length of the string:
input.length() == 8 && input.matches("[a-zA-Z0-9]+\\s*")
This is also probably more efficient than a complex regex.
You can use this lookahead based regex:
^[a-zA-Z0-9](?!.* [a-zA-Z0-9])[a-zA-Z0-9 ]{7}$
RegEx Demo
^[a-zA-Z0-9] matches an alpha-num char at start
(?!.* [a-zA-Z0-9]) is negative lookahead to make sure that there is no instance of an alpha-num char followed by a space.
[a-zA-Z0-9 ]{7}$ matches 7 chars containing alpha-num char or space.
I'm trying to improve my regex skills, so I have made a basic calculator to practice pattern matching. The user is prompted to enter two integer values into the console, separated by a comma, with no spaces. I'm not worried about the values being too large for int to handle, I just want to cover the case of user entering -0. Positive 0, and all other negative and positive values should be accepted.
A scanner object grabs the input from the user and stores it in a string variable. This variable is then passed to a method with a Pattern and Matcher that does the matching and returns a boolean of whether it matched or not.
String userInput = scanner.next();
//look for only integers, especially excluding -0
if(checkUserMathInputIsGood("REGEX", userInput))
{
int sum;
String[] twoNumbersToAdd = userInput.split(",");
sum = Integer.parseInt(twoNumbersToAdd[0]) + Integer.parseInt(twoNumbersToAdd[1]);
System.out.println(sum);
}
After hours of scouring stackoverflow, javadocs, etc., I've found some solutions which almost work.
http://www.vogella.com/tutorials/JavaRegularExpressions/article.html#regex_negative
http://www.regexplanet.com/advanced/java/index.html
Java regular expression for negative numbers?
The pattern example which begins with "T(blah blah)" didn't work at all, and I can't find a reference to what T is supposed to accomplish. I've come close with:
"-{0,1}(?!0)\\d+,-{0,1}(?!0)\\d+"
Breaking it down, this seems to say: allow a minus sign a minimum of 0 and maximum of 1 times. Do not allow 0 if the so-called "negative lookahead" for the minus sign is true. Then allow any integer value at least one integer long. However, this results in the regex rejecting 0 as well as -0.
Examples of input which should be accepted:
2,3
22,-4
-555,-9
0,88
0,0
Examples of input which should be rejected:
-0,9
432,-0
-0,-0
Any help or suggestions is greatly appreciated.
If I understood the requirements correctly then it should be "-?\\d+,-?\\d+"
^(?:(?:\+?\d+)|(?:-(?!0*,)\d+)),(?:(?:\+?\d+)|(?:-(?!0*$)\d+))$
Demo.
Explanation:
^// match start of line or text
(?:// match either:
(?:// option 1:
\+? // a "+" if possible
\d+ // and any number of digits
)
|// or
(?:// option 2:
- // a "-" sign
(?!//negative lookahead assertion: do NOT match if next is...
0*,//...any number of zeroes and a comma
)
\d+//if we've made it this far, then we know this integer is NOT zero. Match any number of digits.
)
)
,// a comma.
(?:// this pattern is basically the same as the one for the first number.
(?:
\+?
\d+
)
|
(?:
-
(?!
0*$// except this matches the end of a line or text instead of a comma.
)
\d+
)
)
$// end of line or text.
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.
I've this string
String myString ="A~BC~FGH~~zuzy|XX~ 1234~ ~~ABC~01/01/2010 06:30~BCD~01/01/2011 07:45";
and I need to extract these 3 substrings
1234
06:30
07:45
If I use this regex \\d{2}\:\\d{2} I'm only able to extract the first hour 06:30
Pattern depArrHours = Pattern.compile("\\d{2}\\:\\d{2}");
Matcher matcher = depArrHours.matcher(myString);
String firstHour = matcher.group(0);
String secondHour = matcher.group(1); (IndexOutOfBoundException no Group 1)
matcher.group(1) throws an exception.
Also I don't know how to extract 1234. This string can change but it always comes after 'XX~ '
Do you have any idea on how to match these strings with regex expressions?
UPDATE
Thanks to Adam suggestion I've now this regex that match my string
Pattern p = Pattern.compile(".*XX~ (\\d{3,4}).*(\\d{1,2}:\\d{2}).*(\\d{1,2}:\\d{2})";
I match the number, and the 2 hours with matcher.group(1); matcher.group(2); matcher.group(3);
The matcher.group() function expects to take a single integer argument: The capturing group index, starting from 1. The index 0 is special, which means "the entire match". A capturing group is created using a pair of parenthesis "(...)". Anything within the parenthesis is captures. Groups are numbered from left to right (again, starting from 1), by opening parenthesis (which means that groups can overlap). Since there are no parenthesis in your regular expression, there can be no group 1.
The javadoc on the Pattern class covers the regular expression syntax.
If you are looking for a pattern that might recur some number of times, you can use Matcher.find() repeatedly until it returns false. Matcher.group(0) once on each iteration will then return what matched that time.
If you want to build one big regular expression that matches everything all at once (which I believe is what you want) then around each of the three sets of things that you want to capture, put a set of capturing parenthesis, use Matcher.match() and then Matcher.group(n) where n is 1, 2 and 3 respectively. Of course Matcher.match() might also return false, in which case the pattern did not match, and you can't retrieve any of the groups.
In your example, what you probably want to do is have it match some preceding text, then start a capturing group, match for digits, end the capturing group, etc...I don't know enough about your exact input format, but here is an example.
Lets say I had strings of the form:
Eat 12 carrots at 12:30
Take 3 pills at 01:15
And I wanted to extract the quantity and times. My regular expression would look something like:
"\w+ (\d+) [\w ]+ (\d{1,2}:\d{2})"
The code would look something like:
Pattern p = Pattern.compile("\\w+ (\\d+) [\\w ]+ (\\d{2}:\\d{2})");
Matcher m = p.matcher(oneline);
if(m.matches()) {
System.out.println("The quantity is " + m.group(1));
System.out.println("The time is " + m.group(2));
}
The regular expression means "a string containing a word, a space, one or more digits (which are captured in group 1), a space, a set of words and spaces ending with a space, followed by a time (captured in group 2, and the time assumes that hour is always 0-padded out to 2 digits). I would give a closer example to what you are looking for, but the description of the possible input is a little vague.