I am newbie to java regular expression. I wrote following code for validating the non digit number. If we enter any non digit number it should return false. for me the below code always return false. whats the wrong here?
package regularexpression;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class NumberValidator {
private static final String NUMBER_PATTERN = "\\d";
Pattern pattern;
public NumberValidator() {
pattern = Pattern.compile(NUMBER_PATTERN);
}
public boolean validate(String line){
Matcher matcher = pattern.matcher(line);
return matcher.matches();
}
public static void main(String[] args) {
NumberValidator validator = new NumberValidator();
boolean validate = validator.validate("123");
System.out.println("validate:: "+validate);
}
}
From Java documentation:
The matches method attempts to match the entire input sequence against the pattern.
Your regular expression matches a single digit, not a number. Add + after \\d to matchone or more digits:
private static final String NUMBER_PATTERN = "\\d+";
As a side note, you can combine initialization and declaration of pattern, making the constructor unnecessary:
Pattern pattern = Pattern.compile(NUMBER_PATTERN);
matches "returns true if, and only if, the entire region sequence matches this matcher's pattern."
The string is 3 digits, which doesn't match the pattern \d, meaning 'a digit'.
Instead you want the pattern \d+, meaning 'one or more digits.' This is expressed in a string as "\\d+"
Related
I want to replace some regex with regex in java for e.g.
Requirement:
Input: xyxyxyP
Required Output : xyzxyzxyzP
means I want to replace "(for)+\{" to "(for\{)+\{" . Is there any way to do this?
I have tried the following code
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class ReplaceDemo2 {
private static String REGEX = "(xy)+P";
private static String INPUT = "xyxyxyP";
private static String REGEXREPLACE = "(xyz)+P";
public static void main(String[] args) {
Pattern p = Pattern.compile(REGEX);
// get a matcher object
Matcher m = p.matcher(INPUT);
INPUT = m.replaceAll(REGEXREPLACE);
System.out.println(INPUT);
}
}
but the output is (xyz)+P .
You can achieve it with a \G based regex:
String s = "xyxyxyP";
String pattern = "(?:(?=xy)|(?!^)\\G)xy(?=(?:xy)*P)";
System.out.println(s.replaceAll(pattern, "$0z"));
See a regex demo and an IDEONE demo.
In short, the regex matches:
(?:(?=xy)|(?!^)\\G) - either a location followed with xy ((?=xy)) or the location after the previous successful match ((?!^)\\G)
xy - a sequence of literal characters xy but only if followed with...
(?=(?:xy)*P) - zero or more sequences of xy (due to (?:xy)*) followed with a P.
I've written a really simple regular expression to validate a phone number that I can see works in the engine provided by zytrax.com regex. When I use it in the class to compile as a pattern I get en error with the escaped characters for the Pattern.compile string to process.
package Test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindMainTestExcercisePN {
private static String phone;
private static Matcher matcher;
private boolean getCheckNumber(String pn) {
boolean valid = matcher.matches();
return valid;
}
private void PhoneNumber(String input) {
Pattern pattern = Pattern.compile("^(?:(?:\\+?\\s*1\\s*(?:[.-\\s*]?)(?:[.\\s*-]?))?(?:(\\s*([0-9]|[0-9]|[0-9])\\s*)|([0-9]|[0-9]|[0-9]))\\s*(?:[.-\\s*]?)?)?([0-9]|[0-9]|[0-9]{2})\\s*(?:[.\\s*-]?)(?:[.-\\s*]?)?([0-9]|[0-9]|[0-9]|[0-9]{4})\\s*");
matcher = pattern.matcher(input);
}
public static void main(String[] a) {
FindMainTestExcercisePN ex15 = new FindMainTestExcercisePN();
phone = "1-098-234-5454";
ex15.PhoneNumber(phone);
boolean bool = ex15.getCheckNumber(phone);
System.out.println("The number is valid= " + bool);
}
}
If you take out the escapes it will work just fine (prime ex. 1-345-345-3324) so any suggestions please?
This expression is illegal:
[.-\\s*]
In a character class, the dash character is a range operator, eg [0-9] means "any character in the range 0 to 9"., but here you have coded a range .-\s, which attempts to express "any character in the range dot to 'any whitespace'", which is clearly nonsense.
To code a literal dash in a character class, code it first or last.
If the intention if this expression is "a dot, dash, whitespace or star", then code:
[.\\s*-]
If the star is not intended as a literal, but you want to express "a dot or dash, or any number of whitespace", use this:
([.-]?|\\s*)
you method getCheckNumber always return true
I want to check user name and last name using java regexp.
And I use this pattern
private static final Pattern CHECK_NAME_FIELD_PATTERN = Pattern.compile("\\w+",
Pattern.UNICODE_CHARACTER_CLASS);
public static boolean checkNameField(String name){
return CHECK_NAME_FIELD_PATTERN.matcher(name).matches();
}
But checkNameField("234523") returns true.
It returns true for the numbers because \w would match also the digits.
private static final Pattern CHECK_NAME_FIELD_PATTERN = Pattern.compile("\\p{L}+",
Pattern.UNICODE_CHARACTER_CLASS);
\\p{L} matches any kind of letter from any language.
Hi and happy new year to all of you,
I have a String like "3-5;9-13;15;20-49".
I want to use a RegEx to:
first, check as far as possible, if the syntax is correct... meaning:
the ranges are separated by a semicolon and a range is defined by x-y or just x (where
x and y are decimals) (the order of the ranges or x
I think I must have some mistake(s) in my RegEx, because matches() gives false although
the string is syntactically correct and find() or group() give me the given ranges...??
If I alter the RegEx slightly...I get matches() to return true, but I canĀ“t get the
"ranges" with find() or group().
What am I doing wrong?
regards,
yves
the code:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RangeRegEx {
public static void main(String[] args) {
String rangeExample = "1-5;7;12-22;50-56;60-90;95;";
String rangeRegEx = "(\\d+(-\\d+)?)"; // matches returnes false, but find() and group() return correct groups
System.out.println ("Variant 1 \""+printRegEx(rangeRegEx)+"\":\n--------------------\n");
Pattern mrPattern = Pattern.compile(rangeRegEx);
Matcher m = mrPattern.matcher(rangeExample);
System.out.println ("RegEx matches() -> "+m.matches());
m.reset();
while (m.find()) {
System.out.println(m.group());
}
rangeRegEx = "((\\d+)(-\\d+)?(;)?)+"; // matches() returns true, but find() and group() do not work...
System.out.println ("\n\nVariant 2 \""+printRegEx(rangeRegEx)+"\":\n--------------------\n");
mrPattern = Pattern.compile(rangeRegEx);
m = mrPattern.matcher(rangeExample);
System.out.println ("RegEx matches() -> "+m.matches());
m.reset();
while (m.find()) {
System.out.println(m.group());
}
}
public static String printRegEx(String regEx){
StringBuffer s=new StringBuffer();
for (int c=0;c<regEx.length();c++){
char ch=regEx.charAt(c);
s.append(ch);
if (ch == '\\') s.append("\\");
}
return s.toString();
}
}
Running the code given above prints the following message to the console:
Variant 1 "(\\d+(-\\d+)?)":
--------------------
RegEx matches() -> false
1-5
7
12-22
50-56
60-90
95
Variant 2 "((\\d+)(-\\d+)?(;)?)+":
--------------------
RegEx matches() -> true
1-5;7;12-22;50-56;60-90;95;
Try this one.
(\\d+-\\d+|\\d+)(;(\\d+-\\d+|\\d+))*;?
This defines the following:
1) range is either a number or number-number
2) number is any sequence of digits
3) you have >= 1 ranges, each two consecutive ones are separated by exactly one ;
4) you may have but also may not have ; at the end
Note that 0010-0001 will also be considered a valid range by my regexp.
Based on your comment below: here is what you're trying to achieve.
You need another/simpler regexp for this.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RangeRegEx {
public static void main(String[] args) {
String rangeExample = "1-5;7;12-22;50-56;60-90;95";
String rangeRegEx = "(\\d+-\\d+|\\d+)";
Pattern mrPattern = Pattern.compile(rangeRegEx);
Matcher m = mrPattern.matcher(rangeExample);
while (m.find()) {
System.out.println(m.group(1));
System.out.println("===");
}
}
}
Another example.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RangeRegEx {
public static void main(String[] args) {
String rangeExample = "1-5;7;12-22;50-56;60-90;95;";
String rangeRegEx = "(\\d+-\\d+|\\d+);(\\d+-\\d+|\\d+);(\\d+-\\d+|\\d+);(\\d+-\\d+|\\d+);(\\d+-\\d+|\\d+);(\\d+-\\d+|\\d+);";
Pattern mrPattern = Pattern.compile(rangeRegEx);
Matcher m = mrPattern.matcher(rangeExample);
System.out.println(m.matches());
m.reset();
while (m.find()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
System.out.println(m.group(3));
System.out.println(m.group(4));
System.out.println(m.group(5));
System.out.println(m.group(6));
}
}
}
The matches() method (doc) tries to match the whole input. This is why first .matches() returns false with pattern (\\d+(-\\d+)?) that is made to look for a single range. A call to group() or group(0) returns the whole match if any.
The find() method (doc) tries to match something in the beginning but it does not need to match the whole input, so it does return true with the same pattern and same input.
To find different matches of the same pattern you need to use find() in a loop. Calling match() is useless here.
Remember groups are numbered as encountered starting from the left.
mrPattern = Pattern.compile("((\\d+)(-\\d+)?)(;)?");
m = mrPattern.matcher("1-5;7;12-22;50-56;60-90;95;");
while (m.find()) {
System.out.println(m.group(1));
}
This should capture the ranges into groups. If you don't want that, I will change it.
(\d+-\d+|\d+);?
I tested it on the following strings, all of which match:
3-5;
3-5;9-13;
3-5;9-13;15;
3-5;9-13;15;20-49
If you want to validate the entire string before getting the groups, you can use a positive lookahead like this:
(?=validation_regex)(capture group)
For example:
(?=(?:(?:\d+-\d+|\d+);?)+)(\d+-\d+|\d+);?
The same mechanism is used in password validation.
I am trying to generalise Regex-java like if I give value and pattern than the method should return true or false if the given value matches the given pattern - TRUE else FALSE.
following is the method I tried with simple Alphanumeric
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
public static boolean isValidInput(String value, String pattern) {
boolean isValid = false;
Pattern walletInputPattern = Pattern.compile(pattern);
Matcher walletMatcher = walletInputPattern.matcher(value);
if (walletMatcher.matches()) {
isValid = true;
}
return isValid;
}
public static void main(String args[]) {
String pattern = "^[a-zA-Z0-9]*$";
String inputValue = "45645";
if (isValidInput(inputValue, pattern)) {
System.out.println("Alphanumeric");
} else {
System.out.println("OOPS");
}
}
}
but I gave wrong input and still it prints the TRUE..
what is the mistake I do here....??..
thanks for your inputs and spending your valuable time :)
I believe this lookahead-based regex should work for you:
String pattern = "^(?=.*?[A-Za-z])(?=.*?[0-9])[a-zA-Z0-9]+$";
This ensures that:
There is at least one alphabetic character in the input
There is at least one digit in the input
The input is comprised of ONLY alphanumerics
It is the right result because 45645 is indeed an alphanumeric value.
If you want to make sure the value is a combination of numbers and letters then you need a different expression:
String pattern = "^(?!^[0-9]+$)(?!^[a-zA-Z]+$)[a-zA-Z0-9]+$";
(?!^[0-9]+$): This makes sure the string isn't just a combination of digits.
(?!^[a-zA-Z]+$): This makes sure the string isn't just a combination of letters.
[a-zA-Z0-9]*: This matches a combination of letters and digits.