Regular Expression for specific number of special character - java

I need only specific number of special characters in a password. I tried the following regex
(?=.*[$#!%*?&]{1})
It takes special character from that set but accepts even multiple special characters.
{1} means number of characters from the set I am allowing the string to validate.
For example,
Alpha1? should be true for the above regular expression
#lpha1? should not be validated by above regex because now it has 2 characters from that set.
Can someone please help?
Any help is appreciated. Thanks in advance

Try this Regex:
^[^$#!%*?&\n]*[$#!%*?&][^$#!%*?&\n]*$
Explanation:
^ - asserts the start of the string
[^$#!%*?&\n]* - matches 0+ occurrences of any character that does NOT fall in these set of characters: $, #, !, %, ?, & or a newline character
[$#!%*?&] - matches one occurrence of one of these characters: $, #, !, %, ?, &
[^$#!%*?&\n]* - matches 0+ occurrences of any character that does NOT fall in these set of characters: $, #, !, %, ?, & or a newline character
$ - asserts the end of the string
Click for Demo
JAVA Code:(Generated here)
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = "^[^$#!%*?&\\n]*[$#!%*?&][^$#!%*?&\\n]*$";
final String string = "abc12312\n"
+ "$123\n"
+ "$123?\n"
+ "Alpha1?\n"
+ "#lpha1?";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
Update:
To get the strings with exactly 2 special characters, use this:
^(?:[^$#!%*?&\n]*[$#!%*?&]){2}[^$#!%*?&\n]*$
To get strings with exactly 5 spl. characters, replace {2} with {5}.
To get string with 2-5 special characters, use {2-5}

In Java you can use the method replaceAll to filter all characters up to your set of special characters. The method takes as argument a regular expression. The size of the result represents the count of special characters:
String password = "#foo!";
int size = password.replaceAll("[^$#$!%*?&]","").length();
System.out.println(size);
// will print 2

Related

Find duplicate char sequences in String by regex in Java

I have an input string and I want to use regex to check if this string has = and $, e.g:
Input:
name=alice$name=peter$name=angelina
Output: true
Input:
name=alicename=peter$name=angelina
Output: false
My regex does't work:
Pattern pattern = Pattern.compile("([a-z]*=[0-9]*$])*");
Matcher matcher = pattern.matcher("name=rob$name=bob");
With .matches(), you may use
Pattern pattern = Pattern.compile("\\p{Lower}+=\\p{Lower}+(?:\\$\\p{Lower}+=\\p{Lower}+)*"); // With `matches()` to ensure whole string match
Details
\p{Lower}+ - 1+ lowercase letters (use \p{L} to match any and \p{Alpha} to only match ASCII letters)
= - a = char
\p{Lower}+ - 1+ lowercase letters
(?:\\$\\p{Lower}+=\\p{Lower}+)* - 0 or more occurrences of:
\$ - a $ char
\p{Lower}+=\p{Lower}+ - 1+ lowercase letters, = and 1+ lowercase letters.
See the Java demo:
List<String> strs = Arrays.asList("name=alice$name=peter$name=angelina", "name=alicename=peter$name=angelina");
Pattern pattern = Pattern.compile("\\p{Lower}+=\\p{Lower}+(?:\\$\\p{Lower}+=\\p{Lower}+)*");
for (String str : strs)
System.out.println("\"" + str + "\" => " + pattern.matcher(str).matches());
Output:
"name=alice$name=peter$name=angelina" => true
"name=alicename=peter$name=angelina" => false
You have extra ] and need to escape $ to use it as a character though you also need to match the last parameter without $ so use
([a-z]*=[a-z0-9]*(\$|$))*
• [a-z]*= : match a-z zero or more times, match = character
• [a-z0-9]*(\$|$): match a-z and 0-9, zero or more times, followed by either $ character or end of match.
• ([a-z]*=[a-z0-9]*(\$|$))*: match zero or more occurences of pairs.
Note: use + (one or more matches) instead of * for strict matching as:
([a-z]+=[a-z0-9]+(\$|$))*

How do I write a multi-regex line?

I'm trying to write a line of regex that performs the following:
A string variable that can contain only:
The letters a to z (upper and lowercase) (zero or many times)
The hyphen character (zero or many times)
The single quote character (zero or one time)
The space character (zero or one time)
Tried searching through many regex websites
.matches("([a-zA-Z_0-9']*(\\s)?)(-)?"))
This allows close to what I want, however you cant start typing a-z anymore after you have typed in space character. So it's sequential in a way. I want the validation to allow for any sequence of those factors.
Expected:
Allowed to type a string that has any amount of a-zA-Z, zero to one space, zero to one dash, anywhere throughout the string.
This is a validation for that
"^(?!.*\\s.*\\s)(?!.*'.*')[a-zA-Z'\\s-]*$"
Expanded
^ # Begin
(?! .* \s .* \s ) # Max single whitespace
(?! .* ' .* ' ) # Max single, single quote
[a-zA-Z'\s-]* # Optional a-z, A-Z, ', whitespace or - characters
$ # End
I guess,
^(?!.*([ ']).*\\1)[A-Za-z' -]*$
might work OK.
Here,
(?!.*([ ']).*\\1)
we are trying to say that, if there was horizontal space (\h) or single quote (') twice in the string, exclude those, which we would be then keeping only those with zero or one time of repetition.
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularExpression{
public static void main(String[] args){
final String regex = "^(?!.*([ ']).*\\1)[A-Za-z' -]*$";
final String string = "abcAbc- ";
final Pattern pattern = Pattern.compile(regex);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
Output
Full match: abcAbc-
Group 1: null
If you wish to simplify/modify/explore the expression, it's been explained on the top right panel of regex101.com. If you'd like, you can also watch in this link, how it would match against some sample inputs.
RegEx Circuit
jex.im visualizes regular expressions:

Matching a word with pound (#) symbol in a regex

I have regexp for check if some text containing word (with ignoring boundary)
String regexp = ".*\\bSOME_WORD_HERE\\b.*";
but this regexp return false when "SOME_WORD" starts with # (hashtag).
Example, without #
String text = "some text and test word";
String matchingWord = "test";
boolean contains = text.matches(".*\\b" + matchingWord + "\\b.*");
// now contains == true;
But with hashtag `contains` was false. Example:
text = "some text and #test word";
matchingWord = "#test";
contains = text.matches(".*\\b" + matchingWord + "\\b.*");
//contains == fasle; but I expect true
The \b# pattern matches a # that is preceded with a word character: a letter, digit or underscore.
If you need to match # that is not preceded with a word char, use a negative lookbehind (?<!\w). Similarly, to make sure the trailing \b matches if a non-word char is there, use (?!\w) negative lookahead:
text.matches("(?s).*(?<!\\w)" + matchingWord + "(?!\\w).*");
Using Pattern.quote(matchingWord) is a good idea if your matchingWord can contain special regex metacharacters.
Alternatively, if you plan to match your search words in between whitespace or start/end of string, you can use (?<!\S) as the initial boundary and (?!\S) as the trailing one
text.matches("(?s).*(?<!\\S)" + matchingWord + "(?!\\S).*");
And one more thing: the .* in the .matches is not the best regex solution. A regex like "(?<!\\S)" + matchingWord + "(?!\\S)" with Matcher#find() will be processed in a much more optimized way, but you will need to initialize the Matcher object for that.
If you are looking for words with leading '#', just simple remove the leading '#' from the searchword and use following regex.
text.matches("#\\b" + matchingWordWithoutLeadingHash + "\\b");

regex to remove round brackets from a string

i have a string
String s="[[Identity (philosophy)|unique identity]]";
i need to parse it to .
s1 = Identity_philosphy
s2= unique identity
I have tried following code
Pattern p = Pattern.compile("(\\[\\[)(\\w*?\\s\\(\\w*?\\))(\\s*[|])\\w*(\\]\\])");
Matcher m = p.matcher(s);
while(m.find())
{
....
}
But the pattern is not matching..
Please Help
Thanks
Use
String s="[[Identity (philosophy)|unique identity]]";
String[] results = s.replaceAll("^\\Q[[\\E|]]$", "") // Delete double brackets at start/end
.replaceAll("\\s+\\(([^()]*)\\)","_$1") // Replace spaces and parens with _
.split("\\Q|\\E"); // Split with pipe
System.out.println(results[0]);
System.out.println(results[1]);
Output:
Identity_philosophy
unique identity
You may use
String s="[[Identity (philosophy)|unique identity]]";
Matcher m = Pattern.compile("\\[{2}(.*)\\|(.*)]]").matcher(s);
if (m.matches()) {
System.out.println(m.group(1).replaceAll("\\W+", " ").trim().replace(" ", "_")); // // => Identity_philosphy
System.out.println(m.group(2).trim()); // => unique identity
}
See a Java demo.
Details
The "\\[{2}(.*)\\|(.*)]]" with matches() is parsed as a ^\[{2}(.*)\|(.*)]]\z pattern that matches a string that starts with [[, then matches and captures any 0 or more chars other than line break chars as many as possible into Group 1, then matches a |, then matches and capture any 0 or more chars other than line break chars as many as possible into Group 2 and then matches ]]. See the regex demo.
The contents in Group 2 can be trimmed from whitespace and used as is, but Group 1 should be preprocessed by replacing all 1+ non-word character chhunks with a space (.replaceAll("\\W+", " ")), then trimming the result (.trim()) and replacing all spaces with _ (.replace(" ", "_")) as the final touch.

Can you help with regular expressions in Java?

I have a bunch of strings which may of may not have random symbols and numbers in them. Some examples are:
contains(reserved[j])){
close();
i++){
letters[20]=word
I want to find any character that is NOT a letter, and replace it with a white space, so the above examples look like:
contains reserved j
close
i
letters word
What is the best way to do this?
It depends what you mean by "not a letter", but assuming you mean that letters are a-z or A-Z then try this:
s = s.replaceAll("[^a-zA-Z]", " ");
If you want to collapse multiple symbols into a single space then add a plus at the end of the regular expression.
s = s.replaceAll("[^a-zA-Z]+", " ");
yourInputString = yourInputString.replaceAll("[^\\p{Alpha}]", " ");
^ denotes "all characters except"
\p{Alpha} denotes all alphabetic characters
See Pattern for details.
I want to find any character that is NOT a letter
That will be [^\p{Alpha}]+. The [] indicate a group. The \p{Alpha} matches any alphabetic character (both uppercase and lowercase, it does basically the same as \p{Upper}\p{Lower} and a-zA-Z. The ^ inside group inverses the matches. The + indicates one-or-many matches in sequence.
and replace it with a white space
That will be " ".
Summarized:
string = string.replaceAll("[^\\p{Alpha}]+", " ");
Also see the java.util.regex.Pattern javadoc for a concise overview of available patterns. You can learn more about regexs at the great site http://regular-expression.info.
Use the regexp /[^a-zA-Z]/ which means, everything that is not in the a-z/A-Z characters
In ruby I would do:
"contains(reserved[j]))".gsub(/[^a-zA-Z]/, " ")
=> "contains reserved j "
In Java should be something like:
import java.util.regex.*;
...
String inputStr = "contains(reserved[j])){";
String patternStr = "[^a-zA-Z]";
String replacementStr = " ";
// Compile regular expression
Pattern pattern = Pattern.compile(patternStr);
// Replace all occurrences of pattern in input
Matcher matcher = pattern.matcher(inputStr);
String output = matcher.replaceAll(replacementStr);

Categories