This might be clear to someone familiar with regex expressions but I am not.
Example:
String onlyNumbers = "1233444";
String numbersAndDigits = "123344FF";
if (IS_ONLY_NUMBERS(onlyNumbers))
return true;
if (IS_ONLY_NUMBERS(numbersAndDigits))
return false;
Suggestions? Is there a way to do a similar check without importing libraries?
Try using String.matches("\\d+"). If that statement returns false, then there are characters in your string that are not digits. \d means the character must be a digit, and the + means that every character must be a digit.
Like so:
String onlynumbers = "1233444";
String numbersanddigits = "123344FF";
System.out.println(onlynumbers.matches("\\d+")); // prints "true"
System.out.println(numbersanddigits.matches("\\d+")); // prints "false"
You can try with:
if (onlynumbers.matches("[0-9]+")
return true;
if (numbersanddigits.matches("[0-9]+")
return false;
Also, as a shortcut, you can use \\d+ instead of [0-9]+. It's just a matter of choice which one to pick.
Related
I want to match certain group of characters in a String independent of their order in the String using regex fucntion. However, the only requirement is that they all must be there.
I have tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*[" + t + "].*"))) {
System.out.println(elD);
}
This one checks whether any of the characters are present. But I want all of them to be there.
Also I tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*(" + t + ").*"))) {
System.out.println(elD);
}
This does not work as well. I have searched quite a while but I could not find an example when all of the characters from the pattern must be present in the String independent of their order.
Thanks
You can write regex for this but it would not look nice. If you would want to check if your string contains anywhere x and y you would need to use few times look-ahead like
^(?=.*x)(?=.*y).*$
and use it like
yourStirng.matches(regex);
But this way you would need to create your own method which would generate you dynamic regex and add (?=.*X) for each character you want to check. You would also need to make sure that this character is not special in regex like ? or +.
Simpler and not less effective solution would be creating your own method which would check if your string contains all searched characters, something like
public static boolean containsUnordered(String input, String searchFor){
char[] characters = searchFor.toCharArray();
for (char c: characters)
if (!input.contains(String.valueOf(c)))
return false;
return true;
}
You can built a pattern from the search string using the replaceAll method:
String s = "12";
String pattern = s.replaceAll("(.)", "(?=[^$1]*$1)");
Note: You can't test the same character several times. (i.e. 112 gives (?=[^1]*1)(?=[^1]*1)(?=[^2]*2) that is exactly the same as (?=[^1]*1)(?=[^2]*2))
But in my opinion Pshemo method is probably more efficient.
I'm trying to filter files in a folder. I need the files that don't end with ".xml-test". The following regex works as expected (ok1,ok2,ok3 = false, ok4 = true)
String regex = ".+\\.xml\\-test$";
boolean ok1 = Pattern.matches(regex, "database123.xml");
boolean ok2 = Pattern.matches(regex, "database123.sql");
boolean ok3 = Pattern.matches(regex, "log_file012.txt");
boolean ok4 = Pattern.matches(regex, "database.xml-test");
Now I just need to negate it, but it doesn't work for some reason:
String regex = "^(.+\\.xml\\-test)$";
I still get ok1,ok2,ok3 = false, ok4 = true
Any ideas? (As people pointed, this could be done easily without regex. But for arguments sake assume I have to use a single regex pattern and nothing else (ie !Pattern.matches(..); is also not allowed))
I think you are looking for:
if (! someString.endsWith(".xml-test")) {
...
}
No regular expression required. Throw this into a FilenameFilter as follows:
public accept(File dir, String name) {
return ! name.endsWith(".xml-test");
}
The meaning of ^ changes depending on its position in the regexp. When the symbol is inside a character class [] as the first character, it means negation of the character class; when it is outside a character class, it means the beginning of line.
The easiest way to negate a result of a match is to use a positive pattern in regex, and then to add a ! on the Java side to do the negation, like this:
boolean isGoodFile = !Pattern.matches(regex, "database123.xml");
The following Java regex asserts that a string does NOT end with: .xml-test:
String regex = "^(?:(?!\\.xml-test$).)*$";
This regex walks the string one character at a time and asserts that at each and every position the remainder of the string is not .xml-test.
Simple!
^ - is not a negation in regexp, this is a symbol indicating beginning of line
you probably need (?!X) X, via zero-width negative lookahead
But I suggest you to use File#listFiles method with FilenameFilter implementation:
name.endsWith(".xml-test")
If you really need to test it with regex, then you should use negative lookbehinds from Pattern class:
String reges = "^.*(?<!\\.xml-test)$"
How it works:
first you match whole string: from start (^) all characters (.*),
you check if what have already matched doesn't have ".xml-test" at end (lookbehind at position you already matched),
you test if it's end of string.
So, I need to write a compiler scanner for a homework, and thought it'd be "elegant" to use regex. Fact is, I seldomly used them before, and it was a long time ago. So I forgot most of the stuff about them and needed to have a look around. I used them successfully for the identifiers (or at least I think so, I still need to do some further tests but for now they all look ok), but I have a problem with the numbers-recognition.
The function nextCh() reads the next character on the input (lookahead char). What I'd like to do here is to check if this char matches the regex [0-9]*. I append every matching char in the str field of my current token, then I read the int value of this field. It recognizes a single number input such as "123", but the problem I have is that for the input "123 456", the final str will be "123 456" while I should get 2 separate tokens with fields "123" and "456". Why is the " " being matched?
private void readNumber(Token t) {
t.str = "" + ch; // force conversion char --> String
final Pattern pattern = Pattern.compile("[0-9]*");
nextCh(); // get next char and check if it is a digit
Matcher match = pattern.matcher("" + ch);
while (match.find() && ch != EOF) {
t.str += ch;
nextCh();
match = pattern.matcher("" + ch);
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
Thank you!
PS: I did solve my problem using the code below. Nevertheless, I'd like to understand where the flaw is in my regex expression.
t.str = "" + ch;
nextCh(); // get next char and check if it is a number
while (ch>='0' && ch<='9') {
t.str += ch;
nextCh();
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
EDIT: turns out my regex also doesn't work for the identifiers recognition (again, includes blanks), so I had to switch to a system similar to my "solution" (while with a lot of conditions). Guess I'll need to study the regex again :O
I'm not 100% sure whether this is relevant in your case, but this:
Pattern.compile("[0-9]*");
matches zero or more numbers anywhere in the string, because of the asterisk. I think the space gets matched because it is a match for 'zero numbers'. If you wanted to make sure the char was a number, you would have to match one or more, using the plus sign:
Pattern.compile("[0-9]+");
or, since you are only comparing a single char at a time, just match one number:
Pattern.compile("^[0-9]$");
You should be using the matches method rather than the find method. From the documentation:
The matches method attempts to match the entire input sequence against the pattern
The find method scans the input sequence looking for the next subsequence that matches the pattern.
So in other words, by using find, if the string contains a digit anywhere at all, you'll get a match, but if you use matches the entire string must match the pattern.
For example, try this:
Pattern p = Pattern.compile("[0-9]*");
Matcher m123abc = p.matcher("123 abc");
System.out.println(m123abc.matches()); // prints false
System.out.println(m123abc.find()); // prints true
Use a simpler regex like
/\d+/
Where
\d means a digit
+ means one or more
In code:
final Pattern pattern = Pattern.compile("\\d+");
I need a regex which will satisfy both conditions.
It should give me true only when a String contains both A-Z and 0-9.
Here's what I've tried:
if PNo[0].matches("^[A-Z0-9]+$")
It does not work.
I suspect that the regex below is slowed down by the look-around, but it should work regardless:
.matches("^(?=.*[A-Z])(?=.*[0-9])[A-Z0-9]+$")
The regex asserts that there is an uppercase alphabetical character (?=.*[A-Z]) somewhere in the string, and asserts that there is a digit (?=.*[0-9]) somewhere in the string, and then it checks whether everything is either alphabetical character or digit.
It easier to write and read if you use two separate regular expressions:
String s = "blah-FOO-test-1-2-3";
String numRegex = ".*[0-9].*";
String alphaRegex = ".*[A-Z].*";
if (s.matches(numRegex) && s.matches(alphaRegex)) {
System.out.println("Valid: " + input);
}
Better yet, write a method:
public boolean isValid(String s) {
String n = ".*[0-9].*";
String a = ".*[A-Z].*";
return s.matches(n) && s.matches(a);
}
A letter may be either before or after the digit, so this expression should work:
(([A-Z].*[0-9])|([0-9].*[A-Z]))
Here is a code example that uses this expression:
Pattern p = Pattern.compile("(([A-Z].*[0-9])|([0-9].*[A-Z]))");
Matcher m = p.matcher("AXD123");
boolean b = m.find();
System.out.println(b);
Here is the regex for you
Basics:
Match in the current line of string: .
Match 0 or any amount of any characters: *
Match anything in the current line: .*
Match any character in the set (range) of characters: [start-end]
Match one of the regex from a group: (regex1|regex2|regex3)
Note that the start and end comes from ASCII order and the start must be before end. For example you can do [0-Z], but not [Z-0]. Here is the ASCII chart for your reference
Check the string against regex
Simply call yourString.matches(theRegexAsString)
Check if string contains letters:
Check if there is a letter: yourString.matches(".*[a-zA-Z].*")
Check if there is a lower cased letter: yourString.matches(".*[a-z].*")
Check if there is a upper cased letter: yourString.matches(".*[A-Z].*")
Check if string contains numbers:
yourString.matches(".*[0-9].*")
Check if string contains both number and letter:
The simplest way is to match twice with letters and numbers
yourString.matches(".*[a-zA-Z].*") && yourString.matches(".*[0-9].*")
If you prefer to match everything all together, the regex will be something like: Match a string which at someplace has a character and then there is a number afterwards in any position, or the other way around. So your regex will be:
yourString.matches(".*([a-zA-Z].*[0-9]|[0-9].*[a-zA-Z]).*")
Extra regex for your reference:
Check if the string stars with letter
yourString.matches("[a-zA-Z].*")
Check if the string ends with number
yourString.matches(".*[0-9]")
This should solve your problem:
^([A-Z]+[0-9][A-Z0-9]*)|([0-9]+[A-Z][A-Z0-9]*)$
But it's unreadable. I would suggest to first check input with "^[A-Z0-9]+$", then check with "[A-Z]" to ensure it contains at least one letter then check with "[0-9]" to ensure it contains at least one digit. This way you can add new restrictions easily and code will remain readable.
What about ([A-Z].*[0-9]+)|([0-9].*[A-Z]+) ?
Try using (([A-Z]+[0-9])|([0-9]+[A-Z])) .It should solve.
use this method:
private boolean isValid(String str)
{
String Regex_combination_of_letters_and_numbers = "^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$";
String Regex_just_letters = "^(?=.*[a-zA-Z])[a-zA-Z]+$";
String Regex_just_numbers = "^(?=.*[0-9])[0-9]+$";
String Regex_just_specialcharachters = "^(?=.*[##$%^&+=])[##$%^&+=]+$";
String Regex_combination_of_letters_and_specialcharachters = "^(?=.*[a-zA-Z])(?=.*[##$%^&+=])[a-zA-Z##$%^&+=]+$";
String Regex_combination_of_numbers_and_specialcharachters = "^(?=.*[0-9])(?=.*[##$%^&+=])[0-9##$%^&+=]+$";
String Regex_combination_of_letters_and_numbers_and_specialcharachters = "^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[##$%^&+=])[a-zA-Z0-9##$%^&+=]+$";
if(str.matches(Regex_combination_of_letters_and_numbers))
return true;
if(str.matches(Regex_just_letters))
return true;
if(str.matches(Regex_just_numbers))
return true;
if(str.matches(Regex_just_specialcharachters))
return true;
if(str.matches(Regex_combination_of_letters_and_specialcharachters))
return true;
if(str.matches(Regex_combination_of_numbers_and_specialcharachters))
return true;
if(str.matches(Regex_combination_of_letters_and_numbers_and_specialcharachters))
return true;
return false;
}
You can delete some conditions according to your taste
I want to validate a string which donot have numeric characters.
If my string is "javaABC" then it must be validated
If my string is "java1" then it must not be validated
I want to restrict all the integers.
Try this:
String Text = ...;
boolean HasNoNumber = Text.matches("^[^0-9]*$");
'^[^0-9]*$' = From Start(^) to end ($), there are ([...]) only non(^) number(0-9). You can use '\D' as other suggest too ... but this is easy to understand.
See more info here.
You can use this:
\D
"\D" matches non-digit characters.
Here is one way that you can search for a digit in a String:
public boolean isValid(String stringToValidate) {
if(Pattern.compile("[0-9]").matcher(stringToValidate).find()) {
// The string is not valid.
return false;
}
// The string is valid.
return true;
}
More detail is here:
http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html
The easiest to understand is probably matching for a single digit and if found fail, instead of creating a regexp that makes sure that all characters in the string are non-digits.