Password Regex with ANY THREE combination but no spaces - java

Ensure Password meets the following Criteria
Length: 8-32 characters
Password must contain atleast 3 of the following: Uppercase, Lowercase, Number, Symbol
Password must not contain Spaces
Password Characters allowed:
!##$%^*()_+Aa1~`-={}[]|\:;"',.?/
I tried:
^.*(?=.*[a-z])(?=.*[A-Z])(?=.*[\d\W])^(?!.*[&])(?=.*[!##$%^*()_+Aa1~`\-={}[\]|\:;"',.?/])\S{8,32}$
I have written this Regex, But enforces One uppercase letter which Should not be the case.......It should accept any three combinations of Uppercase, Lowercase, Numbers, Symbols:
!##$%^*()_+Aa1~`-={}[]|\:;"',.?/
The regex limit limit 255 characters. Any suggestions help on this please.

^(?:[A-Z]()|[a-z]()|[0-9]()|[!##$%^*()_+~`={}\[\]|\:;"',.?/-]())+$(?:\1\2\3|\1\2\4|\1\3\4|\2\3\4)
In more readable form:
^
(?:
[A-Z] () |
[a-z] () |
[0-9] () |
[!##$%^*()_+~`={}\[\]|\\:;"',.?/-] ()
)+
$
(?:
\1\2\3 |
\1\2\4 |
\1\3\4 |
\2\3\4
)
What I'm doing is using empty capturing groups as check boxes, tallying which kinds of characters were seen over the course of the match. So, for example, if there's no uppercase letter in the string, group #1 never participates in the match, so \1 won't succeed at the end. Unless all three other groups do participate, the match will fail.
Be aware that this technique doesn't work in all flavors. In JavaScript, for example, a backreference to an empty group always succeeds, even if the group didn't participate in the match.

You can use:
^(?=.*[!##$%^*()_+~`={}|:;"',.?\[\]\/-].*)(?=.*[A-Z].*)(?=.*[a-z].*)[\w!##$%^*()_+~`={}|:;"',.?\[\]\/-]{8,32}$|
^(?=.*[!##$%^*()_+~`={}|:;"',.?\[\]\/-].*)(?=.*\d.*)(?=.*[a-z].*)[\w!##$%^*()_+~`={}|:;"',.?\[\]\/-]{8,32}$|
^(?=.*[!##$%^*()_+~`={}|:;"',.?\[\]\/-].*)(?=.*[A-Z].*)(?=.*\d.*)[\w!##$%^*()_+~`={}|:;"',.?\[\]\/-]{8,32}$|
^(?=.*\d.*)(?=.*[A-Z].*)(?=.*[a-z].*)[\w!##$%^*()_+~`={}|:;"',.?\[\]\/-]{8,32}$
See LiveDemo
If you want a bit more of flexibility you can use this:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Dummy{
public static void main(String []args){
String password = "aaaZZZ111";
String specials = "!##$%^*()_+~`={}|:;\"',.?\\[\\]\\/-";
String uppercase = "A-Z";
String lowercase = "a-z";
String numbers = "\\d";
String all = specials + uppercase + lowercase + numbers;
int min = 8;
int max = 32;
String regex =
"^" + lookahead(specials) + lookahead(uppercase) + lookahead(lowercase) + "[" + all + "]{"+ min +"," + max + "}$|" +
"^" + lookahead(specials) + lookahead(uppercase) + lookahead(numbers) + "[" + all + "]{"+ min +"," + max + "}$|" +
"^" + lookahead(specials) + lookahead(lowercase) + lookahead(numbers) + "[" + all + "]{"+ min +"," + max + "}$|" +
"^" + lookahead(uppercase) + lookahead(lowercase) + lookahead(numbers) + "[" + all + "]{"+ min +"," + max + "}$";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(password);
if (m.find()) {
System.out.println("OK");
} else {
System.out.println("NO MATCH");
}
}
public static String lookahead(String input) {
return "(?=.*[" + input + "].*)";
}
}

Related

split String If get any capital letters

My String:
BByTTheWay .I want to split the string as B By T The Way BByTheWay .That means I want to split string if I get any capital letters and last put the main string as it is. As far I tried in java:
public String breakWord(String fileAsString) throws FileNotFoundException, IOException {
String allWord = "";
String allmethod = "";
String[] splitString = fileAsString.split(" ");
for (int i = 0; i < splitString.length; i++) {
String k = splitString[i].replaceAll("([A-Z])(?![A-Z])", " $1").trim();
allWord = k.concat(" " + splitString[i]);
allWord = Arrays.stream(allWord.split("\\s+")).distinct().collect(Collectors.joining(" "));
allmethod = allmethod + " " + allWord;
// System.out.print(allmethod);
}
return allmethod;
}
It givs me the output: B ByT The Way BByTTheWay . I think stackoverflow community help me to solve this.
You may use this code:
Code 1
String s = "BByTTheWay";
Pattern p = Pattern.compile("\\p{Lu}\\p{Ll}*");
String out = p.matcher(s)
.results()
.map(MatchResult::group)
.collect(Collectors.joining(" "))
+ " " + s;
//=> "B By T The Way BByTTheWay"
RegEx \\p{Lu}\\p{Ll}* matches any unicode upper case letter followed by 0 or more lowercase letters.
CODE DEMO
Or use String.split using same regex and join it back later:
Code 2
String out = Arrays.stream(s.split("(?=\\p{Lu})"))
.collect(Collectors.joining(" ")) + " " + s;
//=> "B By T The Way BByTTheWay"
Use
String s = "BByTTheWay";
Pattern p = Pattern.compile("[A-Z][a-z]*");
Matcher m = p.matcher(s);
String r = "";
while (m.find()) {
r = r + m.group(0) + " ";
}
System.out.println(r + s);
See Java proof.
Results: B By T The Way BByTTheWay
EXPLANATION
--------------------------------------------------------------------------------
[A-Z] any character of: 'A' to 'Z'
--------------------------------------------------------------------------------
[a-z]* any character of: 'a' to 'z' (0 or more
times (matching the most amount possible))
As per requirements, you can write in this way checking if a character is an alphabet or not:
char[] chars = fileAsString.toCharArray();
StringBuilder fragment = new StringBuilder();
for (char ch : chars) {
if (Character.isLetter(ch) && Character.isUpperCase(ch)) { // it works as internationalized check
fragment.append(" ");
}
fragment.append(ch);
}
String.join(" ", fragment).concat(" " + fileAsString).trim(); // B By T The Way BByTTheWay

Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal character range near index 9

I want to match alphanumeric words separated by the operators, +, -, *, /, <, > and ending with a semicolon. There can be whitespace characters in between e.g. the following strings should return true:
first + second;
first - second;
first * second;
first / second;
first;
first + second < third;
third < second * first;
This is what I have tried:
public boolean isExpr(String line) {
// factor = ([A-Za-Z]+|[0-9]+) for example: aasdaa or 23131 or xyz or 1 or a
// simple-expr = (factor {mulop factor} {addop factor {mulop factor}})
// expr = simple-expr compop simple-expr | simple-expr
String factor = new String("([A-Za-Z]+|[0-9]+)");
String mulOp = new String("(\\*|\\/)"); // '*'' or '/'
String addOp = new String("(\\+|\\-)"); // '+' or '-'
String compOp = new String("(\\<|\\="); // '<' or '='
String simpleExpr = new String("(" + factor + " (" + mulOp + " " + factor + ")? (" + addOp + " " + factor + " (" + mulOp + " " + factor + ")?)?");
String expr = new String("(" + simpleExpr + " " + compOp + " " + simpleExpr + ")|" + simpleExpr);
System.out.println(line.matches(expr));
return line.matches(expr);
}
What is wrong with that code and how can I solve it?
I got the below error on executing my code:
Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal character range near index 9
((([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))? ((\+|\-) ([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))?)? (\<|\= (([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-eZ]+|[0-9]+))? ((\+|\-) ([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))?)?)|(([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0
-9]+))? ((\+|\-) ([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))?)?
Your logic is unnecessarily complex and error-prone.
I suggest you, instead of using unnecessarily complex and error-prone logic, simply use the regex, [A-Za-z0-9]+(?:\s*[\/*+\-<>]\s*[A-Za-z0-9]+\s*)*; which covers all the example strings you have posted in the question.
Explanation of the regex:
[A-Za-z0-9]+: 1+ alphabets or digits
(?:: Open non-capturing group
\s*: 0+ whitespace characters
[\/*+\-<>]: One of /, *, +, -, <, >
\s*: 0+ whitespace characters
[A-Za-z0-9]+: 1+ alphabets or digits
\s*: 0+ whitespace characters
): Close non-capturing group
*: Quantifier to make the non-capturing group match 0+ times
;: The charcter literal, ;
Demo:
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
"first + second;",
"first * second;",
"first - second;",
"first / second;",
"first;",
"first + second < third;",
"third < second * first;"
).forEach(s -> System.out.println(isExpr(s)));
}
public static boolean isExpr(String line) {
return line.matches("[A-Za-z0-9]+(?:\\s*[\\/*+\\-<>]\\s*[A-Za-z0-9]+\\s*)*;");
}
}
Output:
true
true
true
true
true
true
true
What went wrong with your code?
Because of the unnecessarily complex logic that you have implemented, one or more of the parentheses in the final regex have not been closed. In addition to that, I can see at least one part where the parenthesis has not been closed e.g.
String compOp = new String("(\\<|\\="); // '<' or '='
It should be
String compOp = new String("(\\<|\\=)"); // '<' or '='
//----------------------------------^
Apart from this, given below are a couple of more things that you should learn/address:
You can simplify the initialization like:
String factor = "[A-Za-z]+|[0-9]+";
String mulOp = "\\*|\\/"; // '*'' or '/'
String addOp = "\\+|\\-"; // '+' or '-'
String compOp = "\\<|\\="; // '<' or '='
Change a-Z to a-z.

Java - take first letter of word and replace with first letter of another word

I need to create a program that displays two words that a user has inputted then I need to display the first and last letter and the number of characters of those two words.
That part is fine. But next I need to switch the first letter of the first word with the first letter of the second word. And then the last letter of the first word with the last letter of the second word. And the same with the second word.
Then I need to do the same with the second word.
I used the code below but it replaces ALL the characters in the first word (that are the same character) with the character from the second word.
Please help. I've been trying to do this for hours!!! And I am very new to this.
public static void main(String[] args)
{
Scanner user_input = new Scanner(System.in);
String word_one;
String word_two;
System.out.print("Enter 2 words on one line separated by at least one space"
+ " (no white space allowed IN each word): ");
word_one = user_input.next( );
word_two = user_input.nextLine( );
System.out.println("\nFirst word you entered is <"
+ word_one
+ "> which is "
+ word_one.length()
+ " characters long.\nIt starts with the character '"
+ word_one.charAt(word_one.length() - word_one.length())
+ "' and ends with the character'"
+ word_one.charAt(word_one.length() - 1)
+ "'");
System.out.println("\nSecond word you entered is <"
+ (word_two.replace(" ", ""))
+ "> which is "
+ (word_two.replace(" ", "")).length()
+ " characters long. \nIt starts with the character '"
+ word_two.charAt(word_two.length() - word_two.length() + 1)
+ "' and ends with the character'"
+ word_two.charAt(word_two.length() - 1) + "'");
user_input.close();
System.out.println("\nNew words: "
+ word_one.replace(
word_one.charAt(word_one.length() - word_one.length()),
word_two.charAt(word_two.length() - word_two.length() + 1))
.replace(
word_one.charAt(word_one.length() - 1),
word_two.charAt(word_two.length() - 1))
+ word_two.replace(
word_two.charAt(word_two.length() - word_two.length() + 1),
word_one.charAt(word_one.length() - word_one.length()))
.replace(
word_two.charAt(word_two.length() - 1),
word_one.charAt(word_one.length() - 1)));
}
replace(...) replaces all the occurences of given substring with another substring. What you're looking for is replaceFirst(...) for replacement of first letter, but replacing last one won't be so easy. In this case, I'd go with usage of substring(...) and manual concatenation.
Alternatively, you can use replaceAll(...) that works with regular expressions and use beginning/end of line/input constructs (^$\A\Z).
This is much easier if you work with char arrays rather than Strings. Then you can just point to the first (wordOne[0]) and last (wordOne[wordOne.length]) elements.
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
final Scanner userInput = new Scanner(System.in);
System.out.print("Enter 2 words on one line separated by at least one space (no white space allowed IN"
+ " each word): ");
final char[] wordOne = nextInput(userInput);
final char[] wordTwo = nextInput(userInput);
System.out.println("\nFirst word you entered is <" + stringOf(wordOne) + "> which is " + wordOne.length
+ " characters long.\nIt starts with the character '" + wordOne[(wordOne.length - wordOne.length)] + "' "
+ "and ends with the character'" + wordOne[wordOne.length - 1] + "'");
System.out.println("\nSecond word you entered is <" + stringOf(wordTwo) + "> which is " + wordTwo.length + " characters long. \nIt starts with the character '" + wordTwo[0] +
"' and ends with the character'" + wordTwo[wordTwo.length - 1] + "'");
userInput.close();
char[] newWordOne = wordOne.clone();
newWordOne[0] = wordTwo[0];
newWordOne[wordOne.length - 1] = wordTwo[wordTwo.length - 1];
char[] newWordTwo = wordTwo.clone();
newWordTwo[0] = wordOne[0];
newWordTwo[wordTwo.length - 1] = wordOne[wordOne.length - 1];
System.out.println("\nNew words: " + stringOf(newWordOne) + " " + stringOf(newWordTwo));
}
private static String stringOf(final char[] word) {
return new String(word);
}
private static char[] nextInput(final Scanner scanner) {
return scanner.next().trim().toCharArray();
}
}
Thanks for all the advice! But as it turns out all I need to do was use substrings and then concatenate them with the first and last letters of the words that I needed. Also, I needed to replace all the spaces " " with "" because it kept switching out letters and spaces and I did not want it to count the spaces.
Hope this helps others!

Selecting and updating all the specific integer values from a string

If I am given a integer value like 100, then I have to update all the occurrences of the text "Writing No 1" to "Writing No 101"
Actual text:
Collection reference 4 -> My Main Text 4 -> It's writing 3 Writing No 1
Writing No 2 Writing NO 3
I have given three previous references.
As I am given the 100, so I output would like this.
Collection reference 4 -> My Main Text 104 -> It's writing 3 Writing No 101
Writing No 102 Writing NO 103
I have given three previous references.
How to update Writing No 1 to Writing NO 101 and other in the same way using Java?
As per my understanding from your question, you got to replace the string based on the integer values.
Better you write a function for the same like this-
String text = new String("Writing No 1");
public void demo(int num) {
text .replace(text.slice(-1), num);
}
Where you can pass any integer value and can even use loop for the multiple string values.
Hope i was helpful.
Not 100% this is what you need, but I'll give it a try:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StackOverflow {
public static void main(String[] args) {
int inc = 100;
String text = "Collection reference 4 -> My Main Text 4 -> It's writing 3 Writing No 1 \nWriting No 2 Writing NO 3 \nI have given three previous references.";
String patten = "(\\D+) (\\d) (\\D+) (\\d) (\\D+) (\\d) (\\D+) (\\d) (\\D+) (\\d) (\\D+) (\\d) (\\D+)";
Pattern pattern = Pattern.compile(patten, Pattern.DOTALL);
Matcher matcher = pattern.matcher(text);
matcher.find();
System.out.println(matcher.group(1) + " " + matcher.group(2) + " " + matcher.group(3) + " "
+ inc(matcher.group(4), inc) + " " + matcher.group(5) + " " + matcher.group(6) + " " + matcher.group(7)
+ " " + inc(matcher.group(8), inc) + " " + matcher.group(9) + " " + inc(matcher.group(10), inc) + " "
+ matcher.group(11) + " " + inc(matcher.group(12), inc) + matcher.group(13));
}
private static int inc(String base, int inc) {
return Integer.valueOf(base) + inc;
}
}

Regex for validating numbers with certain length and beginning

I would like to validate a value which should have numbers only and length should be 11 and should not start with 129.
Is this possible as I am not very efficient in regular expressions?
Use negative lookahead. The regex should be ^(?!129)\d{11}$ Turn that into a Java pattern; escape the backslash.
You can use
String num_regex = "^(?!129)\\b[0-9]{11}\\b";
String testString= "12345678910";
Boolean b = testString.matches(num_regex);
System.out.println("String: " + testString + " :Valid = " + b);
testString= "12945678910";
b = testString.matches(num_regex);
System.out.println("String: " + testString + " :Valid = " + b);
OUTPUT:
String: 12345678910 :Valid = true
String: 12945678910 :Valid = false

Categories

Resources