regex can't get special constructs (?=x) to work - java

I'm trying to get a valid regex to use in java (java.util.regex) that validates the following format:
a number that has max 15 digits, of which 3 MAX digits may be decimal which are preceeded by a separator (,)
So, valid would be:
123456789012345 (15 digits, ok)
12345678901234,1
[EDIT], these should also be valid:
1234567890123,45
123456789012,345
So far i've come up with the following regex pattern:
Pattern = [0-9]{1,15}(\,[0-9]{1,3})?
This checks for a a range of 1 to 15 digits, following by an optional separator followed by another 3 digits. However, this doesnt check the total length of the input. With this regex, a value of 123456789012345,123 would be valid.
So, i thought i'd add an extra expression that checks the total length, and use the "(?=" construct to simulate the logical AND behaviour.
So i started with adding that to my existing regex expression as follows:
Pattern = (?= [0-9]{1,15}(\,[0-9]{1,3})?)
This however results in basically everything i throw at it failing, and i cant get it to work further. I don't see what i'm doing wrong here? After this works, i'd add another expression to check total length, something like (?=.{16}) i think.

[EDIT]
Realised you wanted to accept total length of 16 if there is a ,, and also that you don't really need to use lookaround here, since you only have two cases. This works just fine:
public static boolean isValid(String input) {
return input.matches("^(\\d{0,15}|\\d{1,12},\\d{1,3})$");
}
This returns valid if one of these is true
input consists of 0-15 numbers or
input consists of 1-12 numbers, followed by a ,, followed by 1-3 numbers
[EDIT2]
Ok, new try:
public static boolean isValid(String input) {
return input.matches("^(\\d{0,15}|(?=.{3,16})\\d+,\\d{1,3})$");
}
This returns valid if one of these is true
input consists of 0-15 numbers or
input consists of 3-16 characters, consisting of at least one digit, followed by a ,, followed by 1-3 numbers

What about this one? play it on RegExr
\d{12,15},?\d{3}

this worked for me.
boolean a = Pattern.matches("\\d{15}|\\d{12},\\d{3}", "123456789012345");
System.out.println(a);//true
boolean b = Pattern.matches("\\d{15}|\\d{12},\\d{3}", "123456789012,345");
System.out.println(b);//true
boolean c = Pattern.matches("\\d{15}|\\d{12},\\d{3}", "1234567890123,456");
System.out.println(c);//false
so your regEx is:
\d{15}|\d{12},\d{3}

Try this regex:
^\d{1,12}(?:\d{0,3}|\d{0,2},\d|\d{0,1},\d\d|,\d\d\d)$

Related

Java String pattern with words and numbers

I have some problems with the pattern in Java. I followed all of the steps in Regex but these lines of code are not working!
Pattern p = Pattern.compile("[a-zA-Z]{4}-[0-9]{1}");
if (p.matcher(id).matches())
this.id = id;
else
System.out.println("Wrong format!");
Whenever I type ABCD-0123, it is false and prints out wrong format
[0-9]{1} means only one digit (in the end of you pattern), and you are invoking matches, which considers the whole input.
Either adjust the digits to {4} or whatever you need, or invoke find instead of matches.
The latter (find) will... find the pattern inside your given input, instead of matching against the whole input.
Useful for patterns describing part of the input.
Replace the regex condition by [a-zA-Z]{4}-[0-9]+
[a-zA-Z]{4}: contains letters of the alphabet and must be exactly 4 letters.
Followed by a "-"
Then digits [0-9]+(if you want to set the size of the replace the +
by {n} n is equal to the number of digits

regular expression for validating format of maximum 5 digits in integer part & with maximum 2 decimal digits

I would like to validate a string format that should only contain only numbers with also following conditions both satisfied:
If it is a integer number, the maximum number of digits is 5. For example, 12345 is fine, but 123456 is not fine.
If it is a number with decimal (or decimal fraction), the maximum digits after decimal mark is two. For example, 10,23 is fine, but 10,234 is not fine.
(NOTE: value use comma or dot as decimal point. Please bear in mind that both of the two conditions have to be satisfied. e.g. 123456,12 is not fine because the integer part is more than five digits)
I tried:
// This is the value to be validated
String value = fetchValue();
// my regular expression
String format = "^\\d{0,5}(?:[\\.\\,]\\d{0,2})?$";
boolean isValid = value.matches(format);
The code successfully validated the condition 1, but failed at condition 2, for example value 3,345 passed validation which is not expected.
What is wrong with my regular expression?
This is what you're trying for
"^(?:\\d{1,5}(?:[.,]\\d{0,2})?|[.,]\\d{1,2})$"
Readable version
^
(?:
\d{1,5}
(?: [.,] \d{0,2} )?
| [.,] \d{1,2}
)
$
You can use the one suggested by Wiktor Stribiżew if you want just one reqex;
You can always split it into two based on your conditions.
^\d{5}$
^\d{5}\.\d{2}$
For JAVA:
matches can be used for matching the complete string and the following if should suffice
if(num.matches("\\d{5}") ||num.matches("\\d{5}\\.\\d{2}") ) {
}

One Regular Expression to validate Zip code not working

Below regex (see code snippet) will satisfy all following four conditions:
12345
12345-6789
12345_6789
12345 1234
I need to include a 5th condition which is 123456789 (hence, 9 digits only, no space) I've tried to change the current regex to this ^[0-9]{5}(_|-|\s){0,1}|[0-9]{4} but this doesn't work
public static boolean isZipCodeValid(String zipcode) {
return zipcode.matches("^\\d{5}(?:[-_\\s]\\d{4})?$");
}
I think you shouldn't have a | there:
^[0-9]{5}(_|-|\s){0,1}|[0-9]{4}
^
here!
Delete that and everything should work.
With that | being there, it means that matching [0-9]{4} is an alternative. So it will either match 5 digits or 4. That's why you end up with 2 matches.
Use the following regex:
^\\d{5}(?:[-_\\s]?\\d{4})?$
It has been tested on https://regex101.com
Try to break down your expression and it should become easier to see:
always 5 digits (probably the first not being 0),
a group of 4 digits preceded by either nothing or one of 3 characters.
If you translate that to regex you should get something like (I included the non-0 first digit as well):
[1-9]\d{4}
(x\d{4})? - that's the optional (?) group ((...)) with x being a placeholder. Now translate "either nothing or one of a 3 characters" into an expression and you get [-_ ]?. (Note that I replaced \s with a space because \s includes tabs and other whitespace.
If you take that all to gether you get [1-9]\d{4}([-_ ]?\d{4})?.
Side note: \d matches other digits as well, e.g. arabic ones. You might want to use [0-9] instead.
I come up with a 2nd method which validate against 9 digits only so somewhere in my code I do something like below. Is not the most elegant way but it does what is supposed to...
if(!isUsaZipCodeValid(bo.getZipCode())){
if((isValidDigit9Only(bo.getZipCode()))){
//do nothing
} else {
errors.add("zipCode", new ActionMessage("error.label.zipcode.usa.digits.only"));
}
}
//and these are the two methods.
public static boolean isUsaZipCodeValid(String zipcode){
/*Below regex will satisfy all three condtions for zip-code. E.g-
12345
12345-6789
12345_6789
12345 1234
*/
return zipcode.matches("^\\d{5}(?:[-_\\s]\\d{4})?$");
}
public static boolean isValidDigit9Only(String zipcode){
/*Below regex will satisfy the below condition for the for zip-code. E.g-
123456789
*/
return zipcode.matches("[0-9]{9}");
}

Java Regular Expression to match dollar amounts

This is what i've been using
\$?[0-9]+\.*[0-9]*
But when i was doing some testing i noticed that things like
$$$34.00
would return as a match (but matcher.group()) just returns the matched substring. I don't want it to even pass the regular expression if the user enters more than one dollar sign so i tried this:
\${1}[0-9]+\.*[0-9]*
but this seems to behave the same as the regular expression i first typed. Right now i'm testing this in java but, i plan to use it in c++ using the Boost libraries. But Please don't give me that solution here because i'm trying to learn without someone giving me the answer.
But i do need help making it so the user can only enter one dollar sign (which is what i thought \${1} would do)
I would suggest avoiding the use of regular expressions for currency parsing, esp when Java provides you much simpler ways to solve this problem.
Consider this code:
String str = "$789.11"; // user entered value
Number number = null;
try {
number = NumberFormat.getCurrencyInstance(Locale.US).parse(str);
} catch(ParseException pe) {
// ignore
}
if (number != null) {
// proceed as user entered a good value
}
else {
// user didn't enter a good value
}
Since you're doing this to learn regex...
^\$(([1-9]\d{0,2}(,\d{3})*)|(([1-9]\d*)?\d))(\.\d\d)?$
Breakdown:
^\$ start of string with $ a single dollar sign
([1-9]\d{0,2}(,\d{3})*) 1-3 digits where the first digit is not a 0, followed by 0 or more occurrences of a comma with 3 digits
or
(([1-9]\d*)?\d) 1 or more digits where the first digit can be 0 only if it's the only digit
(\.\d\d)?$ with a period and 2 digits optionally at the end of the string
Matches:
$4,098.09
$4098.09
$0.35
$0
$380
Does not match:
$098.09
$0.9
$10,98.09
$10,980456
You can do something like [^\$]*\$? in the beginning. This would insure that there are no duplicate $ signs, but also matches if there is no $ present.
Also, if you are working with currency (possible decimal and 2 digits after), you should use [\.\d{2}]?.
This says that it can be a match if it's followed by ONE instance of a period and 2 digits or nothing at all. As stated in the comments, it can also match multiple periods in a row, so you shouldn't use the * quantifier after \.
You are missing ^(beginning of string),$(end of string)
^\$\d+([.][0-9]+)?$
i know this is coming late but this seems to work for me
(\$)?[0-9]+\.*[0-9]*
i dont understand why it didnt work for you.
[$](([1-9]+\.?\d*)|([0]\.\d*)|[0]) pattern ideally for this case.
This is standard Perl regex but could be use in JAVA with some libs.

Java: substring.matches numbers

I'm trying to check if a my substring within my teleInput string contain numbers but I can't seem to get it return true. The results always ends up as false, what am I doing wrong.
String teleInput = "(555)555-5555";
boolean returntT = teleInput.substring(1,3).matches(".*[0-9].*");
I'm an extreme beginner so I don't know if I'm missing something obvious, like mixing methods or maybe something is wrong with the rest of my code, either way, I would really appreciate the help!
Your problem is your substring - you are only returning two characters: the second parameter is the index up to, but not including, the last character. To get 3 characters, you need:
teleInput.substring(1,4)
So try this (notice that matches only needs to check that it's "all digits", because the length is already know to be 3):
teleInput.substring(1,4).matches("\\d*");
Or just forget substring and use matches alone:
teleInput.matches(".\\d{3}.*");
Which is the regex for "any character then 3 digits then anything".
But you can validate the entire input in one line:
teleInput.matches("(.\\d{3}){3}\\d");
You might have to read up on regex to understand this pattern, but it works!
Note: matches() must match the entire string to be true.
If you want to check if the 2nd character in your string is number, you can do it like this:
String teleInput = "(555)555-5555";
boolean returntT = teleInput.substring(1,2).matches("[0-9]");
Instead of this line:
boolean returntT = teleInput.substring(1,3).matches(".*[0-9].*");
You should be doing:
boolean returntT = teleInput.substring(1,3).matches("[0-9]+");
OR this:
boolean returntT = teleInput.substring(1,3).matches("\\d{2}");
Regex [0-9]+ will make sure that the given input has only 1 or more digits in it. For good tutorial on regex read: http://www.regular-expressions.info/

Categories

Resources