I'm building a regex pattern to validate my String inputted.
Here is the limitations that i have to include;
The letters a to z (upper and lowercase) (zero or many times)
o The numbers 0 to 9 (between zero and three times)
o The ampersand (&) character (zero or may times)
o The space character (zero or one time)
Here is the regex I built and tested on
[a-zA-Z&]*|[0-9]{0,3}|[\s]?
String p1 = "[a-zA-Z\\&]*|[0-9]{0,3}|[\\s]?" ;
if (bankName.matches(p1) && bankName.length() >= 8) {
System.out.println("Yes");
}
else{
System.out.println("NO");
}
Here is the entries I'm testing against.
tXiPkaodan57yzrCxYjVT
String bankName = "tXiPkaodan57yzrCxYjVT" ;
On the site i'm testing the regex on is not matching because the numbers ( 5 & 7 ) started and is between the letters but I have included in my regex pattern that it should beable to include any numbers range from 0-9, and 0-3 times
https://www.freeformatter.com/java-regex-tester.html#ad-output
The site i tested it on
The bars ('or') in your regexes have the most precedence, so, that regexp reads:
Match if the input is precisely one of:
Either 0 or more characters that ALL match any letter (either case) or an ampersand,
anywhere between 0 and 3 digits
0 or 1 space.
Your input is none of those things; it is a mix of those things. For example, the input 'a1a' does not match your regexp because, well, step through it: the 'a' forces the regexp matcher to pick the first of your 3 options above, and that's.. it. There's no going back now. Your regexp will match the a, fails to match on the 1, and that's the end of it.
So, how do you fix it? Not by sticking with regexp; that's not good solution for this problem. A regexp that precisely does what you asked for is very convoluted.
Instead, why not just loop through each character, and have 4 counters (spaces, digits, letters, and other stuff). For each character increment the right counter. Then at the end, check that the 'other stuff' counter is 0, digits is 3 or less, and spaces is 1 or less, and then it is valid. Otherwise, it is not.
Related
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")
What is the regex for finding if a piece of text is in a particulate format?
Format should follow:
AAAA-123 or AAAA123 (with or without the dash)
Where the first 4 characters are letters in the range A-M and the following 3 characters are numbers with a max of 299.
Example:
ABCD-299 would match
and
ABZR-301 would not match
[A-M]{4}-?[0-2][0-9]{2}
Basically:
[A-M]{4} = 4 of any letters A-M
-? = an optional dash
[0-2] = a single 0,1, or 2
[0-9]{2} = two of any number
limiting the first number to 0-2 effectively limits your number to 299, and allows for 000-299
i'm not sure if you are searching for this in a string or checking that a string equals exactly this... and that context might change how you use the above. for example, if you are testing a string you'll want to wrap it with ^ and $
^[A-M]{4}-?[0-2][0-9]{2}$
^ means beginning of string
[] define a group of potential matches. In this case uppercase A all the way to uppercase M (hyphen is a special char when within [] to denote a range) (note the range utilizes ascii http://www.asciitable.com/ so if you did A-z it would include all those non alphanumeric characters between.
{} define count. in this case exactly 4. you can define a range like {1,3} which means 1 to 3, or {,7} at most 7, or {5,} at least 5
and the ? means that the char before is may or may not be there. in this case the hyphen.
$ means end of string
the ^ and $ are necessary i think. otherwise that regex will match AAAAAAAA-2342347474
anyways, read up on regex. they can be powerful and fun. http://regexr.com/
Pattern p = Pattern.compile("(?=[1-9][0-9]{2})[0-9]*[05]");
Matcher m = p.matcher("101");
while(m.find()){
System.out.println(m.start()+":"+ m.end()+ m.group());
}
Output------ >> 0:210
Please let me know why I am getting output of m.group() as 10 here.
As far as I understand m.group() should return nothing because [05] matches to nothing.
Your Pattern, (?=[1-9][0-9]{2})[0-9]*[05] consists of 2 parts:
(?=[1-9][0-9]{2})
and
[0-9]*[05]
The first part is a zero-width positive lookahead which searches for a number of length 3, and the first can not be 0. This matches your 101.
The second part searches for any amount of numbers and then a 0 or a 5. This matches the first 2 characters of 101, thus the result is 10.
See Java - Pattern for more information.
What your Regex is looking for is:
[1-9]:
match a single character present in the list below
1-9 a single character in the range between 1 and 9
[0-9]{2}:
match a single character present in the list below
Quantifier: {2} Exactly 2 times
0-9 a single character in the range between 0 and 9
[0-9]*:
match a single character present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
[05]:
match a single character present in the list below
05 a single character in the list 05 literally
for the String "101" this nacht the first 2 chars 101,
so you are printing.out:
System.out.println(**m.start()**+":"+ **m.end()**+ m.group());
where m.start() returns the start index of the previous match(char at
0). where m.end() returns the offset after the last character matched.
and where m.group() returns the input subsequence matched by the previous
match.
That regex was meant to match a number that's a multiple of 5 and greater than or equal to 100, but it's useless without anchors. It should be:
^(?=[1-9][0-9]{2}$)[0-9]*[05]$
The anchors ensure that both the lookahead and the main part are examining the whole of the string. But the task doesn't require a lookahead anyway; this works just fine:
^[1-9][0-9][05]$
As #AlanMoore states, there has to be an alignment.
Assertions are a self contained entity, all they have to do is Pass
to advance to the next construct.
Lets see what (?=[1-9][0-9]{2}) matches;
1111111110666
2222222222222222225666
33333333333333333333333330666
So far so good, on to the next construct.
Lets see what [0-9]*[05] matches.
What ever this matches is the final answer.
1111111110666
2222222222222222225666
33333333333333333333333330666
What to learn is that to get a cohesive answer, assertions have to be crafted to
coincide with constructs that come after them.
Here is an example of a constraint that could be applied
after the assertion.
The assertion state's it needs three digits and the first digit must be >= 1.
The constructs after the assertion state it can be any number of digit's,
as long as it ends with a 0 or 5.
This last part is distressing since it will match only the 500000
So for sure, you need at least three digits.
That can be done like this:
[0-9]{2,}[05]
This says two things
There must be at least three digits, but can be more
It must end with a 0 or 5.
That's it, put it all together, its:
(?=[1-9][0-9]{2})[0-9]{2,}[05]
Of course, this can be condensed to;
[1-9][0-9]+[05]
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.