Problem with formatting a regular expression - java

I am trying to format this regular expression into a String pattern
(^(234\d{7,12})$)|(\b(234\d{7,12}\b\s*,\s*)(\b(234\d{7,12})\b)*)
This is an accurate regex (a has been validated in regexpal.com as being so)
But when I try it in java, it shows errors. And even if I escape it using //, It still dosen't give an accurate Logic. Please. How can I solve this.
package MCast;
import java.util.StringTokenizer;
import java.util.regex.*;
import javax.swing.JOptionPane;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author nnanna
*/
public class Verify {
private static final String STOP = "STOP";
private static final String VALID = "Valid Java Identifier";
private static final String INVALID = " Not Valid Number Format: Must be of the form 23400000023";
private static final String VALID_IDENTIFIER_PATTERN = "(^(234\\d{7,12})$)|(\\b(234\\d{7,12}\\b\\s*,\\s*)(\\b(234\\d{7,12})\\b)*)";
// private static final String VALID_IDENTIFIER_PATTERN2 = "[[2-3][2-3][3-4][0-9]*[ ][2-3][2-3][3-4][0-9]*]*";//[,][2[0-9]]{11}]*";
static String str;
boolean reply;
public Verify() {
}
public int countNo(String stringToCount) {
int j = stringToCount.length();
int count = 0;
for (int i = 0; i < j; i++) {
if (stringToCount.charAt(i) == ',') {
count += 1;
}
}
// System.out.println(count);
return count + 1;
}
public boolean pattern(String str){
Matcher match;
Pattern pattern = Pattern.compile(VALID_IDENTIFIER_PATTERN);
match = pattern.matcher(str);
if (match.matches()) {
reply = true;
JOptionPane.showMessageDialog(null, str + ":\n" + reply + "\n" +countNo(str));
} else {
reply = false;
JOptionPane.showMessageDialog(null, str + ":\n" + reply + "\n");
}
return reply;
}
public static void main(String args[]){
Verify a = new Verify();
String test1 = "23439869450";
String test2 = "23439869450,23439869450";
String test3 = "23439869450,23439869450,23439869450";
String test4 = "23439869450,23439869450,23439869450,23439869450,23439869450,23439869450";
String test5 = "07039869450,23439869450,23439869450,23439869450,23439869450,23439869450";
// a.pattern(test1);
// System.out.println(a.countNo(test1));
a.pattern(test3);
System.out.println(a.countNo(test2));
System.out.println(a.pattern(test1));
System.out.println(a.pattern(test2));
System.out.println(a.pattern(test3));
System.out.println(a.pattern(test4));
System.out.println(a.pattern(test4));
//
// a.pattern(null);
// System.out.println(a.countNo(test1));
}
}

You need to double the backslashes. And your regex isn't doing what you think it is. Use this:
Pattern regex = Pattern.compile(
"^\n" +
"234\\d{7,12}\\s*,\\s*234\\d{7,12} # match a pair\n" +
"(?:\\s*,\\s*234\\d{7,12}\\s*,\\s*234\\d{7,12})* # optionally match more pairs\n" +
"$",
Pattern.COMMENTS);
Matcher regexMatcher = regex.matcher(subjectString);
foundMatch = regexMatcher.matches();
This allows pairs of numbers starting with 234; 10-15 digits long. All numbers must be comma-separated.

don't you mean escaping the \ with \\ and not //
ex : \\d

Related

I have Return type masked Credit Card from which I need to Find Card Type

I am Passing creditCardNumber as 4242***4242
which is masked. How I can get Card Type based on Masked credit card number?
String regVisa = "^4[0-9]{2}(?:[0-9]{3})?$";
String reVisa = "(?:4[0-9]{12}(?:[0-9]{3})?$)";
String regMaster = "^5[1-5][0-9]{14}$";
String regExpress = "^3[47][0-9]{13}$";
String regDiners = "^3(?:0[0-5]|[68][0-9])[0-9]{11}$";
String regDiscover = "^6(?:011|5[0-9]{2})[0-9]{12}$";
String regJCB= "^(?:2131|1800|35\\d{3})\\d{11}$";
if(creditCardNumber.matches(regVisa))
return "visa";
if (creditCardNumber.matches(regMaster))
return "mastercard";
if (creditCardNumber.matches(regExpress))
return "amex";
if (creditCardNumber.matches(regDiners))
return "DINERS";
if (creditCardNumber.matches(regDiscover))
return "discover";
if (creditCardNumber.matches(regJCB))
return "jcb";
if (creditCardNumber.matches(reVisa))
return "VISA";
return "invalid";
Maybe, you have to design some "masked" expression for each, such as:
^4[0-9]{2}[0-9]\\*{3}[0-9]{4}$
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class re{
public static void main(String[] args){
final String regex = "^4[0-9]{2}[0-9]\\*{3}[0-9]{4}$";
final String string = "4242***4242\n"
+ "5242***4242";
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));
}
}
}
}
Output
Full match: 4242***4242
If you wish to explore/simplify/modify 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:

Java regex - Determine which capture group was matched and count occurences

Suppose that I want to build a very large regex with capture groups on run-time based on user's decisions.
Simple example:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
static boolean findTag, findWordA, findOtherWord, findWordX;
static final String TAG = "(<[^>]+>)";
static final String WORD_A = "(wordA)";
static final String OTHER_WORD = "(anotherword)";
static final String WORD_X = "(wordX)";
static int tagCount = 0;
static int wordACount = 0;
static int otherWordCount = 0;
static int wordXCount = 0;
public static void main(String[] args) {
// Boolean options that will be supplied by the user
// make them all true in this example
findTag = true;
findWordA = true;
findOtherWord = true;
findWordX = true;
String input = "<b>this is an <i>input</i> string that contains wordX, wordX, anotherword and wordA</b>";
StringBuilder regex = new StringBuilder();
if (findTag)
regex.append(TAG + "|");
if (findWordA)
regex.append(WORD_A + "|");
if (findOtherWord)
regex.append(OTHER_WORD + "|");
if (findWordX)
regex.append(WORD_X + "|");
if (regex.length() > 0) {
regex.setLength(regex.length() - 1);
Pattern pattern = Pattern.compile(regex.toString());
System.out.println("\nWHOLE REGEX: " + regex.toString());
System.out.println("\nINPUT STRING: " + input);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
// only way I know of to find out which group was matched:
if (matcher.group(1) != null) tagCount++;
if (matcher.group(2) != null) wordACount++;
if (matcher.group(3) != null) otherWordCount++;
if (matcher.group(4) != null) wordXCount++;
}
System.out.println();
System.out.println("Group1 matches: " + tagCount);
System.out.println("Group2 matches: " + wordACount);
System.out.println("Group3 matches: " + otherWordCount);
System.out.println("Group4 matches: " + wordXCount);
} else {
System.out.println("No regex to build.");
}
}
}
The problem is that I can only count each group's matches only when I know beforehand which regex/groups the user wants to find.
Note that the full regex will contain a lot more capture groups and they will be more complex.
How can I determine which capture group was matched so that I can count each group's occurrences, without knowing beforehand which groups the user wants to find?
construct the regex to used named groups:
(?<tag>wordA)|(?<wordx>wordX)|(?<anotherword>anotherword)

Regex for replacing specific characters before and after specific substring

I am going through the Java CodingBat exercises. Here is the one I have just completed:
Given a string and a non-empty word string, return a string made of each char just before and just after every appearance of the word in the string. Ignore cases where there is no char before or after the word, and a char may be included twice if it is between two words.
My code, which works:
public String wordEnds(String str, String word){
String s = "";
String n = " " + str + " "; //To avoid OOB exceptions
int sL = str.length();
int wL = word.length();
int nL = n.length();
int i = 1;
while (i < nL - 1) {
if (n.substring(i, i + wL).equals(word)) {
s += n.charAt(i - 1);
s += n.charAt(i + wL);
i += wL;
} else {
i++;
}
}
s = s.replaceAll("\\s", "");
return s;
}
My question is about regular expressions. I want to know if the above is doable with a regex statement, and if so, how?
You can use Java regex objects Pattern and Matcher for doing this.
public class CharBeforeAndAfterSubstring {
public static String wordEnds(String str, String word) {
java.util.regex.Pattern p = java.util.regex.Pattern.compile(word);
java.util.regex.Matcher m = p.matcher(str);
StringBuilder beforeAfter = new StringBuilder();
for (int startIndex = 0; m.find(startIndex); startIndex = m.start() + 1) {
if (m.start() - 1 > -1)
beforeAfter.append(Character.toChars(str.codePointAt(m.start() - 1)));
if (m.end() < str.length())
beforeAfter.append(Character.toChars(str.codePointAt(m.end())));
}
return beforeAfter.toString();
}
public static void main(String[] args) {
String x = "abcXY1XYijk";
String y = "XY";
System.out.println(wordEnds(x, y));
}
}
(?=(.|^)XY(.|$))
Try this.Just grab the captures and remove the None or empty values.See demo.
https://regex101.com/r/sJ9gM7/73
To get a string containing the character before and after each occurrence of one string within the other, you could use the regex expression:
"(^|.)" + str + "(.|$)"
and then you could iterate through the groups and concatenate them.
This expression will look for (^|.), either the start of the string ^ or any character ., followed by str value, followed by (.|$), any character . or the end of the string $.
You could try something like this:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public String wordEnds(String str, String word){
Pattern p = Pattern.compile("(.)" + str + "(.)");
Matcher m = p.matcher(word);
String result = "";
int i = 0;
while(m.find()) {
result += m.group(i++);
}
return result;
}

split the string using regex when there is no delimeters using java

I have a string eg : DIGITAL SPORTS$8.95HD AO$9.95UCC REC$1.28RENTAL FEE$7.00LOCAL FRANCHISE$4.67
Now I want to split the string and create a map as
DIGITAL SPORTS $8.95
HD AO $9.95
UCC REC $1.28
RENTAL FEE $7.00
LOCAL FRANCHISE $4.67
I wrote a regular expression to split the string. Please find below piece of code
private static String ledgerString = "DIGITAL SPORTS$8.95HD AO$9.95UCC REC$1.28RENTAL FEE$7.00LOCAL FRANCHISE$4.67";
private static Pattern pattern1 = Pattern.compile("([[a-zA-Z ]*\\$[0-9]*.[0-9][0-9]]*)");
private static Matcher matcher = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
matcher = pattern1.matcher(ledgerString.trim());
if (matcher.find()) {
System.out.println(matcher.group(1));
}
}
could you please some one help me how to extract the data from the above string
Your pattern in group 1 is in character class [...] which is probably now that you ware trying to do. Maybe change your pattern to
Pattern.compile("([a-zA-Z ]*)(\\$[0-9]*.[0-9][0-9]*)");
and use it like this
while (matcher.find()) {
System.out.println(matcher.group(1)+" "+matcher.group(2));
}
Also since Java7 you can name groups (?<name>...) so this is also possible
Pattern.compile("(?<name>[a-zA-Z ]*)(?<price>\\$[0-9]*.[0-9][0-9]*)");
while (matcher.find()) {
System.out.println(matcher.group("name")+" "+matcher.group("price"));
}
Output
DIGITAL SPORTS $8.95
HD AO $9.95
UCC REC $1.28
RENTAL FEE $7.00
LOCAL FRANCHISE $4.67
private static String ledgerString = "DIGITAL SPORTS$8.95HD AO$9.95UCC REC$1.28RENTAL FEE$7.00LOCAL FRANCHISE$4.67";
private static Pattern pattern1 = Pattern.compile("([a-zA-Z ]+)(\\$[0-9]*\\.[0-9][0-9])");
private static Matcher matcher = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
matcher = pattern1.matcher(ledgerString.trim());
while (matcher.find()) {
System.out.println(matcher.group(1) + " " + matcher.group(2));
}
}
Try this:
The Regex: (?:(.+?)(\$\d*(?:\.\d+)?))
String regex = "(?:(.+?)(\\$\\d*(?:\\.\\d+)?))";
Demo
Maybe you could replace all occurrences of the "$" symbol with ",$" (comma dollar) symbol. After which you may split it using "," (comma). Do something like:
ledgerString = ledgerString.replaceAll("$", ",$");
String[] tokens = ledgerString.split(",");
The regex you want to use is one that matches each String that you are interested in. Therefore you want to use
Pattern.compile("([a-zA-Z]\$[0-9].[0-9][0-9])");
as this identifies each 'line' you're interested in. You can then use split("$") on each line to separate description from price.
Here is, yet another way of doing that:
String mainString = "DIGITAL SPORTS$8.95HD AO$9.95UCC REC$1.28RENTAL FEE$7.00LOCAL FRANCHISE$4.67";
String[] splittedArray = mainString.split("[0-9][A-Z]");
int currentLength = 0;
for(int i =0; i < splittedArray.length; i++) {
String splitedString;
if(i == 0) {
char endChar = mainString.charAt(splittedArray[i].length());
splitedString = splittedArray[i] + endChar;
currentLength += splittedArray[i].length();
}
else if(i == splittedArray.length -1){
char beginChar = mainString.charAt(currentLength + 1);
splitedString = beginChar + splittedArray[i];
}
else {
char beginChar = mainString.charAt(currentLength + 1);
char endChar = mainString.charAt(currentLength+splittedArray[i].length()+2);
splitedString = beginChar + splittedArray[i] + endChar;
currentLength += splittedArray[i].length()+2;
}
System.out.println(splitedString);
}

String contains at least one digit

I am trying to see whether a string contains at least a digit or a lowercase or an uppercase.
I have written something like this:
int combinations = 0;
string pass = "!!!AAabas1";
if (pass.matches("[0-9]")) {
combinations = combinations + 10;
}
if (pass.matches("[a-z]")) {
combinations =combinations + 26;
}
if (pass.matches("[A-Z]")) {
combinations =combinations + 26;
}
However I don't understand why I cannot get combinations to go to 36. They just remain at 0. What am I doing wrong?
You could use Pattern instead, I think "matches" method looks for the whole string to match the regular expression.
Try the next code:
int combinations = 0;
String pass = "!!AAabas1";
if (Pattern.compile("[0-9]").matcher(pass).find()) {
combinations = combinations + 10;
}
if (Pattern.compile("[a-z]").matcher(pass).find()) {
combinations = combinations + 26;
}
if (Pattern.compile("[A-Z]").matcher(pass).find()) {
combinations = combinations + 26;
}
Here's my attempt. Note, this uses unicode categories for validation so is non-latin language friendly.
import java.util.regex.Pattern;
public class PasswordValidator {
public static void main(String[] args) {
final PasswordValidator passwordValidator = new PasswordValidator();
for (String password : new String[] { "abc", "abc123", "ABC123", "abc123ABC", "!!!AAabas1", "гшщз",
"гшщзЧСМИ22" }) {
System.out.printf("Password '%s' is %s%n", password, passwordValidator.isValidPassword(password) ? "ok"
: "INVALID");
}
}
private static final Pattern LOWER_CASE = Pattern.compile("\\p{Lu}");
private static final Pattern UPPER_CASE = Pattern.compile("\\p{Ll}");
private static final Pattern DECIMAL_DIGIT = Pattern.compile("\\p{Nd}");
/**
* Determine if a password is valid.
*
* <p>
* A password is considered valid if it contains:
* <ul>
* <li>At least one lower-case letter</li>
* <li>At least one upper-case letter</li>
* <li>At least one digit</li>
* </p>
*
* #param password
* password to validate
* #return True if the password is considered valid, otherwise false
*/
public boolean isValidPassword(final String password) {
return containsDigit(password) && containsLowerCase(password) && containsUpperCase(password);
}
private boolean containsDigit(final String str) {
return DECIMAL_DIGIT.matcher(str).find();
}
private boolean containsUpperCase(final String str) {
return UPPER_CASE.matcher(str).find();
}
private boolean containsLowerCase(final String str) {
return LOWER_CASE.matcher(str).find();
}
}
Here's the output:
Password 'abc' is INVALID
Password 'abc123' is INVALID
Password 'ABC123' is INVALID
Password 'abc123ABC' is ok
Password '!!!AAabas1' is ok
Password 'гшщз' is INVALID
Password 'гшщзЧСМИ22' is ok
The problem is that matches tries to match the entire input string.
Instead, try creating a Pattern, then from there create a Matcher, and then use the find method.
The Pattern javadoc should help a great deal.
While using a regex for this can obviously work, Guava's CharMatcher class might be a bit more appropriate to what you're trying to do:
if (CharMatcher.inRange('0', '9').matchesAnyOf(pass))
combinations += 10;
if (CharMatcher.inRange('a', 'z').matchesAnyOf(pass))
combinations += 26;
if (CharMatcher.inRange('A', 'Z').matchesAnyOf(pass))
combinations += 26;
String str_rno = "CooL8";
boolean Flag = false;
String[] parts = str_rno.split("");
for (int i = 0; i < str_rno.length(); i++) {
String part1 = parts[i + 1];
if (Character.isDigit(str_rno.charAt(i))) {
System.out.println(" " + i + " " + part1 + " digit");
Flag = true;
} else {
System.out.println(" " + i + " " + part1 + " char ");
}
}
if(Flag==true){
Toast.makeText(getApplicationContext(),"String contain 1 digit",Toast.LENGTH_SHORT).show();
}
if(Flag==flase){
Toast.makeText(getApplicationContext(),"String not contain 1 digit",Toast.LENGTH_SHORT).show();
}
If you don't want to or are not allowed to use a regex you can also use the following method:
public static boolean containsNumber(String value) {
for (int i = 0; i < value.length(); i++) {
if (Character.isDigit(value.charAt(i)))
return true;
}
return false;
}
It goes through the string until it finds a number. If no number was found, then false is returned. However, I suspect that for longer strings the regex variant has better performance.

Categories

Resources