i'm trying to capture only the two 6's adjacent to each other and get how many times did it occur using regex like if we had 794234879669786694326666976 the answer should be 2 or if its 66666 it should be zero and so on i'm using the following code and captured it by this (66)* and using matcher.groupcount() to get how many times did it occur but its not working !!!
package me;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class blah {
public static void main(String[] args) {
// Define regex to find the word 'quick' or 'lazy' or 'dog'
String regex = "(66)*";
String text = "6678793346666786784966";
// Obtain the required matcher
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
int match=0;
int groupCount = matcher.groupCount();
System.out.println("Number of group = " + groupCount);
// Find every match and print it
while (matcher.find()) {
match++;
}
System.out.println("count is "+match);
}
}
One approach here would be to use lookarounds to ensure that you match only islands of exactly two sixes:
String regex = "(?<!6)66(?!6)";
String text = "6678793346666786784966";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
This finds a count of two, for the input string you provided (the two matches being the 66 at the very start and end of the string).
The regex pattern uses two lookarounds to assert that what comes before the first 6 and after the second 6 are not other sixes:
(?<!6) assert that what precedes is NOT 6
66 match and consume two 6's
(?!6) assert that what follows is NOT 6
You need to use
String regex = "(?<!6)66(?!6)";
See the regex demo.
Details
(?<!6) - no 6 right before the current location
66 - 66 substring
(?!6) - no 6 right after the current location.
See the Java demo:
String regex = "(?<!6)66(?!6)";
String text = "6678793346666786784966";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(text);
int match=0;
while (matcher.find()) {
match++;
}
System.out.println("count is "+match); // => count is 2
This didn't take long to come up with. I like regular expressions but I don't use them unless really necessary. Here is one loop method that appears to work.
char TARGET = '6';
int GROUPSIZE = 2;
// String with random termination character that's not a TARGET
String s = "6678793346666786784966" + "z";
int consecutiveCount = 0;
int groupCount = 0;
for (char c : s.toCharArray()) {
if (c == TARGET) {
consecutiveCount++;
}
else {
// if current character is not a TARGET, update group count if
// consecutive count equals GROUPSIZE
if (consecutiveCount == GROUPSIZE) {
groupCount++;
}
// in any event, reset consecutive count
consecutiveCount = 0;
}
}
System.out.println(groupCount);
What is the best way to use regex to get the highest number in a group of strings that match a certain pattern.
For example:
Suppose I wanted to find the next integer to suffix an Untitled file.
Here is an example of already existing file names:
Untitled1.java -> should match
untitled2.java -> should match (case insensitive)
MyFile.java -> should not match (does not contain Untitled#.java)
NotUntitled3.java -> should not match (does not exactly match Untitled#.java)
In this example the function below should return: 3
public int getNextUntitledFileSuffix(String[] fileNames){
int nextSuffix = 1;
int maxSuffix = 1;
for (int i = 0; i < fileNames.length; i++){
//use regex to set nextSuffix
}
return nextSuffix;
}
You can use this code to extract the numeric portion from the untitledNNN.java file name:
Pattern p = Pattern.compile("^untitled(\\d+)[.]java$", Pattern.CASE_INSENSITIVE);
for (String fileName : fileNames) {
Matcher m = p.matcher(fileName);
if (!m.find()) {
continue;
}
String digits = m.group(1);
... // Parse and find the max
}
Demo.
Since you are OK with throwing an exception when the number does not fit in an int, you could mark your method with throws NumberFormatException, and use Integer.parseInt(digits) to get the value. After that you could compare the number with maxSuffix, a running max value of the sequence. You should start maxSuffix at zero, not at one, because you will increment it at the end.
To avoid an overflow, check if maxSuffix is equal to Integer.MAX_VALUE before returning maxSuffix+1.
I added the rest of the logic based on dasblinkenlight's answer:
public int getNextUntitledFileSuffix(List<String> fileNames) throws NumberFormatException
{
int maxSuffix = 0;
final Pattern pattern = Pattern.compile("^untitled(\\d+)[.]java$", Pattern.CASE_INSENSITIVE);
for (String fileName : fileNames)
{
Matcher matcher = pattern.matcher(fileName);
if (matcher.find())
{
int suffix = Integer.parseInt(matcher.group(1));
if (suffix > maxSuffix)
{
maxSuffix = suffix;
}
}
}
return maxSuffix + 1;
}
I'm trying to validate Utopian ID number using java regex classes, ie Pattern and Matcher.
The following are the conditions which needs to be satisfied,
The string must begin with between 0-3 (inclusive) lowercase alphabets.
Immediately following the letters, there must be a sequence of digits (0-9), The length of this segment must be between 2 and 8, both inclusive.
Immediately following the numbers, there must be atleast 3 uppercase letters.
Following is the code which I've written,
public class Solution{public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int ntc;
String[] str;
try {
ntc = Integer.parseInt(br.readLine());
str = new String[ntc];
for (int i = 0; i < ntc; i++)
str[i] = br.readLine();
for (int i = 0; i < ntc; i++)
if (validate(str[i]))
System.out.println("VALID");
else
System.out.println("INVALID");
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean validate(String str) {
Pattern pr = Pattern.compile("[a-z]{0,3}[0-9]{2,8}[A-Z]{3,}");
Matcher mr = pr.matcher(str);
return mr.find();
}}
The following is the input and its respective o/p
I/P:
3
n761512618TUKEFQROSWNFWFWEQEXKPWYYCRK
rRf99
198VLHJIYVEBODQCQEGYGECOGRMQPE
O/P:
VALID
INVALID
VALID
The first testcase is Invalid as it has nine numbers instead of maximum of eight. However it says Valid.
Is there anything wrong in the Regex pattern which I've written.?
Use start and end anchors in your regex in-order to do an exact string match.
Pattern pr = Pattern.compile("^[a-z]{0,3}[0-9]{2,8}[A-Z]{3,}$");
Without anchors, it would match from the middle of a string also.
Use Matcher.matches() rather than Matcher.find(), in order to match the regexp against the entire string:
private static boolean validate(String str) {
Pattern pr = Pattern.compile("[a-z]{0,3}[0-9]{2,8}[A-Z]{3,}");
Matcher mr = pr.matcher(str);
return mr.matches();
}
Also, since the pattern never changes, I would move it into a constant so that it won't be recompiled every time the method is called:
static final Pattern UTOPIAN_ID_PATTERN =
Pattern.compile("[a-z]{0,3}[0-9]{2,8}[A-Z]{3,}");
private static boolean validate(final String str) {
Matcher mr = UTOPIAN_ID_PATTERN.matcher(str);
return mr.matches();
}
I am currently struggling with my "dirty word" filter finding partial matches.
example: if I pass in these two params replaceWord("ass", "passing pass passed ass")
to this method
private static String replaceWord(String word, String input) {
Pattern legacyPattern = Pattern.compile(word, Pattern.CASE_INSENSITIVE);
Matcher matcher = legacyPattern.matcher(input);
StringBuilder returnString = new StringBuilder();
int index = 0;
while(matcher.find()) {
returnString.append(input.substring(index,matcher.start()));
for(int i = 0; i < word.length() - 1; i++) {
returnString.append('*');
}
returnString.append(word.substring(word.length()-1));
index = matcher.end();
}
if(index < input.length() - 1){
returnString.append(input.substring(index));
}
return returnString.toString();
}
I get p*sing p*s p**sed **s
When I really just want "passing pass passed **s.
Does anyone know how to avoid this partial matching with this method??
Any help would be great thanks!
This tutorial from Oracle should point you in the right direction.
You want to use a word boundary in your pattern:
Pattern p = Pattern.compile("\\bword\\b", Pattern.CASE_INSENSITIVE);
Note, however that this still is problematic (as profanity filtering always is). A "non-word character" that defines the boundary is anything not included in [0-9A-Za-z_]
So for example, _ass would not match.
You also have the problem of profanity derived terms ... where the term is prepended to say, "hole", "wipe", etc
I'm working on a dirty word filter as we speak, and the option I chose to go with was Soundex and some regex.
I first filter out strange character with \w which is [a-zA-Z_0-9].
Then use soundex(String) to make a string that you can check against the soundex string of the word you want to test.
String soundExOfDirtyWord = Soundex.soundex(dirtyWord);
String soundExOfTestWord = Soundex.soundex(testWord);
if (soundExOfTestWord.equals(soundExOfDirtyWord)) {
System.out.println("The test words sounds like " + dirtyWord);
}
I just keep a list of dirty words in the program and have SoundEx run through them to check. The algorithm is something worth looking at.
You could also use replaceAll() method from the Matcher class. It replaces all the occurences of the pattern with your specified replacement word. Something like below.
private static String replaceWord(String word, String input) {
Pattern legacyPattern = Pattern.compile("\\b" + word + "\\b", Pattern.CASE_INSENSITIVE);
Matcher matcher = legacyPattern.matcher(input);
String replacement = "";
for (int i = 0; i < word.length() - 1; i++) {
replacement += "*";
}
replacement += word.charAt(word.length() - 1);
return matcher.replaceAll(replacement);
}
How do you check if a String contains a special character like:
[,],{,},{,),*,|,:,>,
Pattern p = Pattern.compile("[^a-z0-9 ]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("I am a string");
boolean b = m.find();
if (b)
System.out.println("There is a special character in my string");
If you want to have LETTERS, SPECIAL CHARACTERS and NUMBERS in your password with at least 8 digit, then use this code, it is working perfectly
public static boolean Password_Validation(String password)
{
if(password.length()>=8)
{
Pattern letter = Pattern.compile("[a-zA-z]");
Pattern digit = Pattern.compile("[0-9]");
Pattern special = Pattern.compile ("[!##$%&*()_+=|<>?{}\\[\\]~-]");
//Pattern eight = Pattern.compile (".{8}");
Matcher hasLetter = letter.matcher(password);
Matcher hasDigit = digit.matcher(password);
Matcher hasSpecial = special.matcher(password);
return hasLetter.find() && hasDigit.find() && hasSpecial.find();
}
else
return false;
}
You can use the following code to detect special character from string.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DetectSpecial{
public int getSpecialCharacterCount(String s) {
if (s == null || s.trim().isEmpty()) {
System.out.println("Incorrect format of string");
return 0;
}
Pattern p = Pattern.compile("[^A-Za-z0-9]");
Matcher m = p.matcher(s);
// boolean b = m.matches();
boolean b = m.find();
if (b)
System.out.println("There is a special character in my string ");
else
System.out.println("There is no special char.");
return 0;
}
}
If it matches regex [a-zA-Z0-9 ]* then there is not special characters in it.
What do you exactly call "special character" ? If you mean something like "anything that is not alphanumeric" you can use org.apache.commons.lang.StringUtils class (methods IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable).
If it is not so trivial, you can use a regex that defines the exact character list you accept and match the string against it.
This is tested in android 7.0 up to android 10.0 and it works
Use this code to check if string contains special character and numbers:
name = firstname.getText().toString(); //name is the variable that holds the string value
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
}
All depends on exactly what you mean by "special". In a regex you can specify
\W to mean non-alpahnumeric
\p{Punct} to mean punctuation characters
I suspect that the latter is what you mean. But if not use a [] list to specify exactly what you want.
Have a look at the java.lang.Character class. It has some test methods and you may find one that fits your needs.
Examples: Character.isSpaceChar(c) or !Character.isJavaLetter(c)
This worked for me:
String s = "string";
if (Pattern.matches("[a-zA-Z]+", s)) {
System.out.println("clear");
} else {
System.out.println("buzz");
}
First you have to exhaustively identify the special characters that you want to check.
Then you can write a regular expression and use
public boolean matches(String regex)
//without using regular expression........
String specialCharacters=" !#$%&'()*+,-./:;<=>?#[]^_`{|}~0123456789";
String name="3_ saroj#";
String str2[]=name.split("");
for (int i=0;i<str2.length;i++)
{
if (specialCharacters.contains(str2[i]))
{
System.out.println("true");
//break;
}
else
System.out.println("false");
}
Pattern p = Pattern.compile("[\\p{Alpha}]*[\\p{Punct}][\\p{Alpha}]*");
Matcher m = p.matcher("Afsff%esfsf098");
boolean b = m.matches();
if (b == true)
System.out.println("There is a sp. character in my string");
else
System.out.println("There is no sp. char.");
//this is updated version of code that i posted
/*
The isValidName Method will check whether the name passed as argument should not contain-
1.null value or space
2.any special character
3.Digits (0-9)
Explanation---
Here str2 is String array variable which stores the the splited string of name that is passed as argument
The count variable will count the number of special character occurs
The method will return true if it satisfy all the condition
*/
public boolean isValidName(String name)
{
String specialCharacters=" !#$%&'()*+,-./:;<=>?#[]^_`{|}~0123456789";
String str2[]=name.split("");
int count=0;
for (int i=0;i<str2.length;i++)
{
if (specialCharacters.contains(str2[i]))
{
count++;
}
}
if (name!=null && count==0 )
{
return true;
}
else
{
return false;
}
}
Visit each character in the string to see if that character is in a blacklist of special characters; this is O(n*m).
The pseudo-code is:
for each char in string:
if char in blacklist:
...
The complexity can be slightly improved by sorting the blacklist so that you can early-exit each check. However, the string find function is probably native code, so this optimisation - which would be in Java byte-code - could well be slower.
in the line String str2[]=name.split(""); give an extra character in Array...
Let me explain by example
"Aditya".split("") would return [, A, d,i,t,y,a] You will have a extra character in your Array...
The "Aditya".split("") does not work as expected by saroj routray you will get an extra character in String => [, A, d,i,t,y,a].
I have modified it,see below code it work as expected
public static boolean isValidName(String inputString) {
String specialCharacters = " !#$%&'()*+,-./:;<=>?#[]^_`{|}~0123456789";
String[] strlCharactersArray = new String[inputString.length()];
for (int i = 0; i < inputString.length(); i++) {
strlCharactersArray[i] = Character
.toString(inputString.charAt(i));
}
//now strlCharactersArray[i]=[A, d, i, t, y, a]
int count = 0;
for (int i = 0; i < strlCharactersArray.length; i++) {
if (specialCharacters.contains( strlCharactersArray[i])) {
count++;
}
}
if (inputString != null && count == 0) {
return true;
} else {
return false;
}
}
Convert the string into char array with all the letters in lower case:
char c[] = str.toLowerCase().toCharArray();
Then you can use Character.isLetterOrDigit(c[index]) to find out which index has special characters.
Use java.util.regex.Pattern class's static method matches(regex, String obj)
regex : characters in lower and upper case & digits between 0-9
String obj : String object you want to check either it contain special character or not.
It returns boolean value true if only contain characters and numbers, otherwise returns boolean value false
Example.
String isin = "12GBIU34RT12";<br>
if(Pattern.matches("[a-zA-Z0-9]+", isin)<br>{<br>
System.out.println("Valid isin");<br>
}else{<br>
System.out.println("Invalid isin");<br>
}