Regex to validate that every digit is different from each other - java

I have to validate strings with specific conditions using a regex statement. The condition is that every digit is different from each other. So, 123 works but not 112 or 131.
So, I wrote a statement which filters a string according to the condition and prints true once a string fullfies everything, however it only seems to print "true" altough some strings do not meet the condition.
public class MyClass {
public static void main(String args[]) {
String[] value = {"123","951","121","355","110"};
for (String s : value){
System.out.println("\"" + s + "\"" + " -> " + validate(s));
}
}
public static boolean validate(String s){
return s.matches("([0-9])(?!\1)[0-9](?!\1)[0-9]");
}
}

#Vinz's answer is perfect, but if you insist on using regex, then you can use:
public static boolean validate(String s) {
return s.matches("(?!.*(.).*\\1)[0-9]+");
}

You don't need to use regex for that. You can simply count the number of unique characters in the String and compare it to the length like so:
public static boolean validate(String s) {
return s.chars().distinct().count() == s.length();
}

Related

How do I check if the number of occurrences of two words in a String is Equal without using loops?

I am trying to find out if there is the same number of occurrences "dog" and "cat" are in the given String.
It should return true if they are equal, or false otherwise. How can I find out this without while, for etc. loops?
This is my current process
class Main {
public static boolean catsDogs(String s) {
String cat = "cat";
String dog = "dog";
if (s.contains(cat) && s.contains(dog)) {
return true;
}
return false;
}
public static void main(String[] args) {
boolean r = catsDogs("catdog");
System.out.println(r); // => true
System.out.println(catsDogs("catcat")); // => false
System.out.println(catsDogs("1cat1cadodog")); // => true
}
}
With java9+ the regex matcher has a count method:
public static boolean catsDogs(String s) {
Pattern pCat = Pattern.compile("cat");
Pattern pDog = Pattern.compile("dog");
Matcher mCat = pCat.matcher(s);
Matcher mDog = pDog.matcher(s);
return (mCat.results().count() == mDog.results().count());
}
You can use the following example by replacing the string (in case you don't want the split to be placed) :
public static boolean catsDogs(String s) {
return count(s,"cat") == count(s,"dog");
}
public static int count(String s, String catOrDog) {
return (s.length() - s.replace(catOrDog, "").length()) / catOrDog.length();
}
public static void main(String[] args) {
boolean r = catsDogs("catdog");
System.out.println(r); // => true
System.out.println(catsDogs("catcat")); // => false
System.out.println(catsDogs("1cat1cadodog")); // => true
}
Here's a couple of single-line solutions based on Java 9 Matcher.result() which produces a stream of MatchResult corresponding to each matching subsequence in the given string.
We can also make this method more versatile by providing a pair of regular expressions as arguments instead of hard-coding them.
teeing() + summingInt()
We can turn the stream of MatchResesult into a stream of strings by generating matching groups. And collect the data using collector teeing() expecting as its arguments two downstream collectors and a function producing the result based on the values returned by each collector.
public static boolean hasSameFrequency(String str,
String regex1,
String regex2) {
return Pattern.compile(regex1 + "|" + regex2).matcher(str).results()
.map(MatchResult::group)
.collect(Collectors.teeing(
Collectors.summingInt(group -> group.matches(regex1) ? 1 : 0),
Collectors.summingInt(group -> group.matches(regex2) ? 1 : 0),
Objects::equals
));
}
collectingAndThen() + partitioningBy()
Similarly, we can use a combination of collectors collectingAndThen() and partitioningBy().
The downside of this approach in comparison to the one introduced above is that partitioningBy() materializes stream elements as the values of the map (meanwhile we're interested only their quantity), but it performs fewer comparisons.
public static boolean hasSameFrequency(String str,
String regex1,
String regex2) {
return Pattern.compile(regex1 + "|" + regex2).matcher(str).results()
.map(MatchResult::group)
.collect(Collectors.collectingAndThen(
Collectors.partitioningBy(group -> group.matches(regex1)),
map -> map.get(true).size() == map.get(false).size()
));
}

How can Java remove leading whitespace?

I have been trying to figure out why this Java code won't delete any leading whitespace to my actual string, I have been trying to use stripLeading() method and the trim(); method, and various other methods with the same functionality but still haven't gotten a favorable outcome. Code:
public static String message(String logLine) {
logLine = (String) logLine.subSequence(logLine.indexOf(" ") + 1, logLine.length());
return logLine;
}
public static void main(String[] args) {
System.out.println(message("[WARNING]: \tTimezone not set \r\n"));
}
What results is what I wanted, just the words "Timezone not set" however I want this program to completely ignore leading whitespace, which for some reason it can't. Thank you for any help.
Possible solutions
Use String::replaceFirst to keep only the part after a prefix ([WARNING]:) followed by whitespaces and the main part:
public static String message(String logLine) {
return logLine.replaceFirst("^\\S*\\s+(\\S+(\\s+\\S+)*)\\s+$", "$1");
}
As the prefix ends with ':', a solution offered in the comment using String::substring + String::trim works too:
public static String message(String logLine) {
return logLine.substring(logLine.indexOf(":") + 1).trim();
}

Java recursive method that removes all instances of a second string in the first string and returns the new first string

I am trying to write a recursive method in Java that accepts two strings and then goes ahead and removes the instances of the second string from the first string (one at a time).
ex. String 1 == Mississippi, String 2 iss
first recursion == Missippi
then the final result should return Mippi
public class RecursionEx {
public static void main(String[] args) {
String str1 = "Mississippi";
String str2 = "iss";
System.out.println(repString(str1, str2));
}
public static String repString(String string1, String string2) {
//base case
if(string1.length()== 0)
return "";
//recursive case
if (string1.substring(0, string2.length()) == string2)
return repString(string1.substring(string2.length()), string2);
else
return repString(string1.substring(1), string2);
}}
Like the comment suggests, you should use equals() when comparing strings in Java, but you can also simplify your life by using the contains and removeFirst method for strings to deal with this recursive task.
I added a print line to the recursive function to show it is removing one instance of string2 at a time from string1.
public class StringRecursion {
public static void main(String[] args) {
String str1 = "Mississippi";
String str2 = "iss";
System.out.println(repString(str1, str2));
}
public static String repString(String string1, String string2) {
if(string1.contains(string2)) {
string1 = string1.replaceFirst(string2, "");
System.out.println("The string is currently: "+ string1);
}
else {
return string1;
}
return repString(string1, string2);
}
}
Output:
The string is currently: Missippi
The string is currently: Mippi
Mippi
Important: One other thing to consider with such an approach is if you want the pattern "iss" formed by an intermediate removal to also be removed. For instance, if you have the word "iissss" and want to remove "iss" it would become "" after running this even though iss does not appear twice in the word initially.
If you want to have the behavior mimic replaceAll function, where we are looking to only get rid of the "iss" patterns in the very first word and not the ones that appear in intermediate steps, I believe the function:
public static String repString(String string1, String string2) {
if(string1.contains(string2)) {
Pattern pattern = Pattern.compile(string2);
long originalCounts = pattern.matcher(string1).results().count();
string1 = string1.replaceFirst(string2, "");
long newCounts = pattern.matcher(string1).results().count();
if(originalCounts == newCounts) {
Matcher matcher = pattern.matcher(string1);
matcher.find();
int startPosition = matcher.end();
//Skip the generated matching pattern that appears in-between.
return string1.substring(0, startPosition) + repString(string1.substring(startPosition), string2);
}
//System.out.println("The string is currently: "+ string1);
}
else {
return string1;
}
return repString(string1, string2);
}
will be sufficient instead.

Java substring string when specific string occurs

i need help to substring a string when a a substring occurs.
Example
Initial string: 123456789abcdefgh
string to substr: abcd
result : 123456789
I checked substr method but it accept index position value.I need to search the occurrence of the substring and than pass the index?
If you want to split the String from the last number (a), then the code would look like this:
you can change the "a" to any char within the string
package nl.testing.startingpoint;
public class Main {
public static void main(String args[]) {
String[] part = getSplitArray("123456789abcdefgh", "a");
System.out.println(part[0]);
System.out.println(part[1]);
}
public static String[] getSplitArray(String toSplitString, String spltiChar) {
return toSplitString.split("(?<=" + spltiChar + ")");
}
}
Bear in mind that toSplitString.split("(?<=" + spltiChar + ")"); splits from the first occurrence of that character.
Hope this might help:
public static void main(final String[] args)
{
searchString("123456789abcdefghabcd", "abcd");
}
public static void searchString(String inputValue, final String searchValue)
{
while (!(inputValue.indexOf(searchValue) < 0))
{
System.out.println(inputValue.substring(0, inputValue.indexOf(searchValue)));
inputValue = inputValue.substring(inputValue.indexOf(searchValue) +
searchValue.length());
}
}
Output:
123456789
efgh
Use a regular expression, like this
static String regex = "[abcd[.*]]"
public String remove(String string, String regex) {
return string.contains(regex) ? string.replaceAll(regex) : string;
}

Regex filename with exactly 2 underscores

I need to match if filenames have exactly 2 underscores and extension 'txt'.
For example:
asdf_assss_eee.txt -> true
asdf_assss_eee_txt -> false
asdf_assss_.txt -> false
private static final String FILENAME_PATTERN = "/^[A-Za-z0-9]+_[A-Za-z0-9]+_[A- Za-z0-9]\\.txt";
does not working.
You just need to add + after the third char class and you must remove the first forward slash.
private static final String FILENAME_PATTERN = "^[A-Za-z0-9]+_[A-Za-z0-9]+_[A-Za-z0-9]+\\.txt$";
You can use a regex like this with insensitive flag:
[a-z\d]+_[a-z\d]+_[a-z\d]+\.txt
Or with inline insensitive flag
(?i)[a-z\d]+_[a-z\d]+_[a-z\d]+\.txt
Working demo
In case you want to shorten it a little, you could do:
([a-z\d]+_){2}[a-z\d]+\.txt
Update
So lets assume you want to at least one or more characters after the second underscore, before the file extension.
Regex is still not "needed" for this. You could split the String by the underscore and you should have 3 elements from the split. If the 3rd element is just ".txt" then it's not valid.
Example:
public static void main(String[] args) throws Exception {
String[] data = new String[] {
"asdf_assss_eee.txt",
"asdf_assss_eee_txt",
"asdf_assss_.txt"
};
for (String d : data) {
System.out.println(validate(d));
}
}
public static boolean validate(String str) {
if (!str.endsWith(".txt")) {
return false;
}
String[] pieces = str.split("_");
return pieces.length == 3 && !pieces[2].equalsIgnoreCase(".txt");
}
Results:
true
false
false
Old Answer
Not sure I understand why your third example is false, but this is something that can easily be done without regex.
Start with checking to see if the String ends with ".txt", then check if it contains only two underscores.
Example:
public static void main(String[] args) throws Exception {
String[] data = new String[] {
"asdf_assss_eee.txt",
"asdf_assss_eee_txt",
"asdf_assss_.txt"
};
for (String d : data) {
System.out.println(validate(d));
}
}
public static boolean validate(String str) {
if (!str.endsWith(".txt")) {
return false;
}
return str.chars().filter(c -> c == '_').count() == 2;
}
Results:
true
false
true
Use this Pattern:
Pattern p = Pattern.compile("_[^_]+_[^_]+\\.txt")
and use .find() instead of .match() in the Matcher:
Matcher m = p.matcher(filename);
if (m.find()) {
// found
}

Categories