I want to restrict getGatewaySerialNumber from taking special characters.
I have written these condition but if block it is executing only first condition it is not checking for and condition.
How to restrict Gatewayserialnumber from taking special character.
If(manifestRequestEntity.getGatewaySerialNumber().lenghth()>16 && manifestRequestEntity.getGatewaySerialNumber().matches(regex :"[0-9a-fA-F]+"))
You can use some helper methods to check if it only contains alphabets and numbers
something like this :
public static boolean checkForSpecialChar(String stringToCheck){
char ch[] = stringToCheck.toCharArray();
for(int i=0; i<ch.length; i++)
{
if((ch[i]>='A' && ch[i]<='Z') || (ch[i]>='a' && ch[i]<='z') || (ch[i]>='0' && ch[i]<='9'))
{
continue;
}
return true;
}
return false;
}
Try This.
name = "abc";
Pattern special= Pattern.compile("[^a-z0-9 ]", Pattern.CASE_INSENSITIVE);
Pattern number = Pattern.compile("[0-9]", Pattern.CASE_INSENSITIVE);
Matcher matcher = special.matcher(name);
Matcher matcherNumber = number.matcher(name);
boolean constainsSymbols = matcher.find();
boolean containsNumber = matcherNumber.find();
if(constainsSymbols){
//string contains special symbol/character
}
else if(containsNumber){
//string contains numbers
}
else{
//string doesn't contain special characters or numbers
}
Related
For example, if the given string is "HELLO world", the output should be true as the string has satisfied at least one lowercase letter condition.
try {
Pattern pattern = Pattern.compile("^\w*[a-z]\w*$");
Matcher matcher = pattern.matcher(password);
result = matcher.matches();
} catch (Exception e) {
//print something
}
It is not the cleanest solution, but looping through the String like this would also get you the result you want. This function returns true when the string holds one not capital letter.
It doesn't use regex but it also gives you the option to check the String characters for other things you need to verify.
private static boolean checkString(String str) {
char ch;
boolean lowerCaseFlag = false;
for(int i=0;i < str.length();i++) {
ch = str.charAt(i);
if (Character.isLowerCase(ch)) {
lowerCaseFlag = true;
}
}
return lowerCaseFlag;
}
I'm writing a program where the user enters a String in the following format:
"What is the square of 10?"
I need to check that there is a number in the String
and then extract just the number.
If i use .contains("\\d+") or .contains("[0-9]+"), the program can't find a number in the String, no matter what the input is, but .matches("\\d+")will only work when there is only numbers.
What can I use as a solution for finding and extracting?
try this
str.matches(".*\\d.*");
If you want to extract the first number out of the input string, you can do-
public static String extractNumber(final String str) {
if(str == null || str.isEmpty()) return "";
StringBuilder sb = new StringBuilder();
boolean found = false;
for(char c : str.toCharArray()){
if(Character.isDigit(c)){
sb.append(c);
found = true;
} else if(found){
// If we already found a digit before and this char is not a digit, stop looping
break;
}
}
return sb.toString();
}
Examples:
For input "123abc", the method above will return 123.
For "abc1000def", 1000.
For "555abc45", 555.
For "abc", will return an empty string.
I think it is faster than regex .
public final boolean containsDigit(String s) {
boolean containsDigit = false;
if (s != null && !s.isEmpty()) {
for (char c : s.toCharArray()) {
if (containsDigit = Character.isDigit(c)) {
break;
}
}
}
return containsDigit;
}
s=s.replaceAll("[*a-zA-Z]", "") replaces all alphabets
s=s.replaceAll("[*0-9]", "") replaces all numerics
if you do above two replaces you will get all special charactered string
If you want to extract only integers from a String s=s.replaceAll("[^0-9]", "")
If you want to extract only Alphabets from a String s=s.replaceAll("[^a-zA-Z]", "")
Happy coding :)
The code below is enough for "Check if a String contains numbers in Java"
Pattern p = Pattern.compile("([0-9])");
Matcher m = p.matcher("Here is ur string");
if(m.find()){
System.out.println("Hello "+m.find());
}
I could not find a single pattern correct.
Please follow below guide for a small and sweet solution.
String regex = "(.)*(\\d)(.)*";
Pattern pattern = Pattern.compile(regex);
String msg = "What is the square of 10?";
boolean containsNumber = pattern.matcher(msg).matches();
Pattern p = Pattern.compile("(([A-Z].*[0-9])");
Matcher m = p.matcher("TEST 123");
boolean b = m.find();
System.out.println(b);
The solution I went with looks like this:
Pattern numberPat = Pattern.compile("\\d+");
Matcher matcher1 = numberPat.matcher(line);
Pattern stringPat = Pattern.compile("What is the square of", Pattern.CASE_INSENSITIVE);
Matcher matcher2 = stringPat.matcher(line);
if (matcher1.find() && matcher2.find())
{
int number = Integer.parseInt(matcher1.group());
pw.println(number + " squared = " + (number * number));
}
I'm sure it's not a perfect solution, but it suited my needs. Thank you all for the help. :)
Try the following pattern:
.matches("[a-zA-Z ]*\\d+.*")
Below code snippet will tell whether the String contains digit or not
str.matches(".*\\d.*")
or
str.matches(.*[0-9].*)
For example
String str = "abhinav123";
str.matches(".*\\d.*") or str.matches(.*[0-9].*) will return true
str = "abhinav";
str.matches(".*\\d.*") or str.matches(.*[0-9].*) will return false
As I was redirected here searching for a method to find digits in string in Kotlin language, I'll leave my findings here for other folks wanting a solution specific to Kotlin.
Finding out if a string contains digit:
val hasDigits = sampleString.any { it.isDigit() }
Finding out if a string contains only digits:
val hasOnlyDigits = sampleString.all { it.isDigit() }
Extract digits from string:
val onlyNumberString = sampleString.filter { it.isDigit() }
public String hasNums(String str) {
char[] nums = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
char[] toChar = new char[str.length()];
for (int i = 0; i < str.length(); i++) {
toChar[i] = str.charAt(i);
for (int j = 0; j < nums.length; j++) {
if (toChar[i] == nums[j]) { return str; }
}
}
return "None";
}
You can try this
String text = "ddd123.0114cc";
String numOnly = text.replaceAll("\\p{Alpha}","");
try {
double numVal = Double.valueOf(numOnly);
System.out.println(text +" contains numbers");
} catch (NumberFormatException e){
System.out.println(text+" not contains numbers");
}
As you don't only want to look for a number but also extract it, you should write a small function doing that for you. Go letter by letter till you spot a digit. Ah, just found the necessary code for you on stackoverflow: find integer in string. Look at the accepted answer.
.matches(".*\\d+.*") only works for numbers but not other symbols like // or * etc.
ASCII is at the start of UNICODE, so you can do something like this:
(x >= 97 && x <= 122) || (x >= 65 && x <= 90) // 97 == 'a' and 65 = 'A'
I'm sure you can figure out the other values...
I am writing a Java program in which I need to search a particular word from a Set. The word that has to be searched is something like ("wo.d") where '.' can be replaced by any other alphabet. I am using regex to match such type of word cases.
This is what I have so far
HashSet<String> words = new HashSet<String>();//this set is already populated
String word = "t.st";
if(word.contains(".")){
Pattern p = Pattern.compile(word);
Matcher m;
boolean match = false;
for(String setWord : words){
m = p.matcher(setWord);
if(m.matches())
match = true;
}
if(match)
System.out.println("Its a match");
else
System.out.println("Its not a match");
}
else{
System.out.println("The word does not contain regex do other stuff");
}
The code above works but is not efficient because it is being called many times in a second. So it produces a lag in the program.
You need to stop iterating as soon as you get a match, so assuming that you use Java 8, your for loop could be rewritten efficiently as next:
boolean match = words.stream().anyMatch(w -> p.matcher(w).matches());
You could also parallelize the research using parallelStream() instead of stream() especially if your Set has a lot of words.
If you don't use Java 7, it could still be done using FluentIterable from Google Guava but without the ability to parallelize the research unfortunately.
boolean match = FluentIterable.from(words).anyMatch(
new Predicate<String>() {
#Override
public boolean apply(#Nullable final String w) {
return p.matcher(w).matches();
}
}
);
But in your case, I don't believe that using FluentIterable can be more interesting than simply adding a break when you get a match, as it will still be easier to read and maintain
if (p.matcher(setWord).matches()) {
match = true;
break;
}
So, if you really need to use a regular expression and you cannot use Java 8, your best option is to use break as described above, there is no magic trick to consider.
Assuming that you will only have one character to replace, it could be done using startsWith(String) and endsWith(String) which will always be much faster than a regular expression. Something like this:
// Your words should be in a TreeSet to be already sorted alphabetically
// in order to get a match as fast as possible
Set<String> words = new TreeSet<String>(); //this set is already populated
int index = word.indexOf('.');
if (index != -1) {
String prefix = word.substring(0, index);
String suffix = word.substring(index + 1);
boolean match = false;
for (String setWord : words){
// From the fastest to the slowest thing to check
// to get the best possible performances
if (setWord.length() == word.length()
&& setWord.startsWith(prefix)
&& setWord.endsWith(suffix)) {
match = true;
break;
}
}
if(match)
System.out.println("Its a match");
else
System.out.println("Its not a match");
}
else {
System.out.println("The word does not contain regex do other stuff");
}
Use TreeSet instead of HashSet. And test for sub range of the set.
TreeSet<String> words = new TreeSet<>();// this set is already populated
String word = "t.st";
if (word.contains(".")) {
String from = word.replaceFirst("\\..*", "");
String to = from + '\uffff';
Pattern p = Pattern.compile(word);
Matcher m;
boolean match = false;
for (String setWord : words.subSet(from, to)) {
m = p.matcher(setWord);
if (m.matches()) {
match = true;
break;
}
}
if (match)
System.out.println("Its a match");
else
System.out.println("Its not a match");
} else {
System.out.println("The word does not contain regex do other stuff");
}
In this case words.subSet(from, to) contains only the words start with "t".
Just break out of loop to stop further regex matching of your HashSet as soon as you get a match:
if(m.matches()) {
match = true;
break;
}
Full Code:
HashSet<String> words = new HashSet<String>();//this set is already populated
String word = "t.st";
if(word.contains(".")){
Pattern p = Pattern.compile(word);
Matcher m;
boolean match = false;
for(String setWord : words){
m = p.matcher(setWord);
if(m.matches()) {
match = true;
break:
}
}
if(match)
System.out.println("Its a match");
else
System.out.println("Its not a match");
}
else{
System.out.println("The word does not contain regex do other stuff");
}
Use original matching method like this.
static boolean match(String wild, String s) {
int len = wild.length();
if (len != s.length())
return false;
for (int i = 0; i < len; ++i) {
char w = wild.charAt(i);
if (w == '.')
continue;
else if (w != s.charAt(i))
return false;
}
return true;
}
and
HashSet<String> words = new HashSet<>();// this set is already populated
String word = "t.st";
boolean match = false;
if (word.contains(".")) {
for (String setWord : words) {
if (match(word, setWord)) {
match = true;
break;
}
}
if (match)
System.out.println("Its a match");
else
System.out.println("Its not a match");
} else {
System.out.println("The word does not contain regex do other stuff");
}
I want to find a single regex which matches the longest numerical string in a URL.
I.e for the URL: http://stackoverflow.com/1234/questions/123456789/ask, I would like it to return : 123456789
I thought I could use : ([\d]+)
However this returns the first match from the left, not the longest.
Any ideas :) ?
This regex will be used as an input to a strategy pattern, which extracts certain characteristics from urls:
public static String parse(String url, String RegEx) {
Pattern pattern = Pattern.compile(regex);
Matcher m = pattern.matcher(url);
if (m.find()) {
return m.group(1);
}
return null;
}
So it would be much tidier if I could use a single regex. :( –
Don't use regex. Just iterate the characters:
String longest = 0;
int i = 0;
while (i < str.length()) {
while (i < str.length() && !Character.isDigit(str.charAt(i))) {
++i;
}
int start = i;
while (i < str.length() && Character.isDigit(str.charAt(i))) {
++i;
}
if (i - start > longest.length()) {
longest = str.substring(start, i);
}
}
#Andy already gave a non-regex answer, which is probably faster, but if you want to use regex, you must, as #Jan points out, add logic, e.g.:
public String findLongestNumber(String input) {
String longestMatch = "";
int maxLength = 0;
Matcher m = Pattern.compile("([\\d]+)").matcher(input);
while (m.find()) {
String currentMatch = m.group();
int currentLength = currentMatch.length();
if (currentLength > maxLength) {
maxLength = currentLength;
longestMatch = currentMatch;
}
}
return longestMatch;
}
t
Not possible with pure Regex, however I would do it this way (using Stream Max and Regex) :
String url = "http://stackoverflow.com/1234/questions/123456789/ask";
Pattern biggest = Pattern.compile("/(\\d+)/");
Matcher m = biggest.matcher(url);
List<String> matches = new ArrayList<>();
while(m.find()){
matches.add(m.group(1));
}
System.out.println(matches.parallelStream().max((String a, String b) -> Integer.compare(a.length(), b.length())).get());
Will print : 123456789
I was given a long text in which I need to find all the text that are embedded in a pair of & (For example, in a text "&hello&&bye&", I need to find the words "hello" and "bye").
I try using the regex ".*&([^&])*&.*" but it doesn't work, I don't know what's wrong with that.
Any help?
Thanks
Try this way
String data = "&hello&&bye&";
Matcher m = Pattern.compile("&([^&]*)&").matcher(data);
while (m.find())
System.out.println(m.group(1));
output:
hello
bye
No regex needed. Just iterate!
boolean started = false;
List<String> list;
int startIndex;
for(int i = 0; i < string.length(); ++i){
if(string.charAt(i) != '&')
continue;
if(!started) {
started = true;
startIndex = i + 1;
}
else {
list.add(string.substring(startIndex, i)); // maybe some +-1 here in indices
}
started = !started;
}
or use split!
String[] parts = string.split("&");
for(int i = 1; i < parts.length; i += 2) { // every second
list.add(parts[i]);
}
If you don't want to use regular expressions, here's a simple way.
String string = "xyz...." // the string containing "hello", "bye" etc.
String[] tokens = string.split("&"); // this will split the string into an array
// containing tokens separated by "&"
for(int i=0; i<tokens.length; i++)
{
String token = tokens[i];
if(token.length() > 0)
{
// handle edge case
if(i==tokens.length-1)
{
if(string.charAt(string.length()-1) == '&')
System.out.println(token);
}
else
{
System.out.println(token);
}
}
}
Two problems:
You're repeating the capturing group. This means that you'll only catch the last letter between &s in the group.
You will only match the last word because the .*s will gobble up the rest of the string.
Use lookarounds instead:
(?<=&)[^&]+(?=&)
Now the entire match will be hello (and bye when you apply the regex for the second time) because the surrounding &s won't be part of the match any more:
List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("(?<=&)[^&]+(?=&)");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
matchList.add(regexMatcher.group());
}
The surrounding .* don't make sense and are unproductive. Just &([^&])*& is sufficient.
I would simplify it even further.
Check that the first char is &
Check that the last char is &
String.split("&&") on the substring between them
In code:
if (string.length < 2)
throw new IllegalArgumentException(string); // or return[], whatever
if ( (string.charAt(0) != '&') || (string.charAt(string.length()-1) != '&')
// handle this, too
String inner = string.substring(1, string.length()-1);
return inner.split("&&");