Here is my problem:
Create a constructor for a telephone number given a string in the form xxx-xxx-xxxx or xxx-xxxx for a local number. Throw an exception if the format is not valid.
So I was thinking to validate it using a regular expression, but I don't know if I'm doing it correctly. Also what kind of exception would I have to throw? Do I need to create my own exception?
public TelephoneNumber(String aString){
if(isPhoneNumberValid(aString)==true){
StringTokenizer tokens = new StringTokenizer("-");
if(tokens.countTokens()==3){
areaCode = Integer.parseInt(tokens.nextToken());
exchangeCode = Integer.parseInt(tokens.nextToken());
number = Integer.parseInt(tokens.nextToken());
}
else if(tokens.countTokens()==2){
exchangeCode = Integer.parseInt(tokens.nextToken());
number = Integer.parseInt(tokens.nextToken());
}
else{
//throw an excemption here
}
}
}
public static boolean isPhoneNumberValid(String phoneNumber){
boolean isValid = false;
//Initialize reg ex for phone number.
String expression = "(\\d{3})(\\[-])(\\d{4})$";
CharSequence inputStr = phoneNumber;
Pattern pattern = Pattern.compile(expression);
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches()){
isValid = true;
}
return isValid;
}
Hi sorry, yes this is homework. For this assignments the only valid format are xxx-xxx-xxxx and xxx-xxxx, all other formats (xxx)xxx-xxxx or xxxxxxxxxx are invalid in this case.
I would like to know if my regular expression is correct
So I was thinking to validate it using a regular expression, but I don't know if I'm doing it correctly.
It indeed looks overcomplicated. Also, matching xxx-xxx-xxxx or xxx-xxxx where x is a digit can be done better with "(\\d{3}-){1,2}\\d{4}". To learn more about regex I recommend to go through http://regular-expressions.info.
Also what kind of exception would I have to throw? Do I need to create my own exception?
A ValidatorException seems straight forward.
public static void isPhoneNumberValid(String phoneNumber) throws ValidatorException {
if (!phoneNumber.matches(regex)) {
throws ValidatorException("Invalid phone number");
}
}
If you don't want to create one yourself for some reasons, then I'd probably pick IllegalArgumentException, but still, I don't recommend that.
That said, this validation of course doesn't cover international and/or external telephone numbers. Unless this is really homework, I'd suggest to rethink the validation.
^(([(]?(\d{2,4})[)]?)|(\d{2,4})|([+1-9]+\d{1,2}))?[-\s]?(\d{2,3})?[-\s]?((\d{7,8})|(\d{3,4}[-\s]\d{3,4}))$
matches:
(0060)123-12345678, (0060)12312345678, (832)123-1234567, (006)03-12345678,
(006)03-12345678, 00603-12345678, 0060312345678
0000-123-12345678, 0000-12-12345678, 0000-1212345678 ... etc.
1234-5678, 01-123-4567
Can replace '-' with SPACE i.e (0080) 123 12345678
Also matches +82-123-1234567, +82 123 1234567, +800 01 12345678 ... etc.
More for house-hold/private number.
Not for 1-800-000-0000 type of number
*Tested with Regex tester http://regexpal.com/
You could match those patterns pretty easily as suggested by BalusC.
As a side note, StringTokenizer has been deprecated. From JavaDoc:
StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.
An easier way to split your string into the appropriate segments would be:
String phoneParts[] = phoneNumber.split("-");
String pincode = "589877";
Pattern pattern = Pattern.compile("\\d{6}");
\d indicates the digits. inside the braces the number of digits
Matcher matcher = pattern.matcher(pincode);
if (matcher.matches()) {
System.out.println("Pincode is Valid");
return true;
} else {
System.out.println("pincode must be a 6 digit Number");
Related
How to check whether a string is present on another string in Java, but here the conditions be like:
For Example:
String 1: Panda
String 2: "a1d22n333a4444p"
Here String 2 needs to have the letter 'p','n','d' at-least once and 'a' at-least twice. Pattern should be matches with the above conditions.
I have done with Regular Expression, but i am not getting the solution.
public static boolean isContainsAnimal(String message,String animal) {
String animalPattern=generatePattern("panda");
Pattern pattern = Pattern.compile(animalPattern);
Matcher matcher = pattern.matcher(message);
int count = 0;
while (matcher.find()) {
count++;
}
if(count>=1){
return true;
}else
{
return false;
}
}
public static String generatePattern(String animal){
String result="";
for(int i=0;i<animal.length();i++){
result+="[^"+animal.charAt(i)+"]*"+animal.charAt(i);
}
return result;
}
Suggest me a solution for this problem.
Your attempt does not take account of the different possible orderings of the characters in the animal string. In fact, for a 5 distinct character string, there are 5 factorial different orders.
It is possible to generate a regex with all of the orderings as alternates, but the result is ... horrible and inefficient.
A better idea is to work out if there are letters (like 'a') are repeated. Then generate a regex for each letter, use "match" to apply each one and AND the results.
An even better idea is to not use regexes at all. They are the wrong tool for this job.
I am trying to set requirements for a certain number that a user requiers to enter(pNumber). pNumber should consist of 2 letters then 6 letters or numbers and finally a number.
I have implemented a method i found here on stackoverflow, but when i enter a number like: "LL^&%JJk9" it still gives me a positive result?
to my understanding .matches checks that a string only consists of the given values?
String First = pNumber.substring(0, 2);
String Middle = pNumber.substring(2, 8);
String Last = pNumber.substring(8, 9);
if (First.matches(".*[a-zA-Z].*") && Middle.matches(".*[a-zA-Z0-9].*") && Last.matches(".*[0-9].*")) {
greenOk.setVisibility(View.VISIBLE);
nextBtn.setEnabled(true);
} else {
redCross.setVisibility(View.VISIBLE);
}
You could use Apache Commons Lang for that. There you have methods like isNumeric and isAlphanumeric
Or use methods like Character isDigit
Maybe something like:
String input1 = "TYe4r5t12";
String input2 = "LL^&%JJk9";
String pattern = "([a-zA-Z]{2}[a-zA-Z0-9]{6}[0-9]{1})";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(input1);
if (m.find()) {
System.out.println("Valid !!!");
}else{
System.out.println("Invalid !!!");
}
TextUtils class has various methods and one of them is given below.
TextUtils.isDigitsOnly(string)
This Stackoverflow details how to use Apache Commons to solve your problem.
If you are looking for a Regular Expression route of solving your issue, this will likely help you:
if(pNumber.matches("[a-zA-Z]{2}[a-zA-Z0-9]{6}[0-9]")) {
greenOk.setVisibility(View.VISIBLE);
nextBtn.setEnabled(true);
} else {
redCross.setVisibility(View.VISIBLE);
}
I want regex to validate for only letters and spaces. Basically this is to validate full name. Ex: Mr Steve Collins or Steve Collins I tried this regex. "[a-zA-Z]+\.?" But didnt work. Can someone assist me please
p.s. I use Java.
public static boolean validateLetters(String txt) {
String regx = "[a-zA-Z]+\\.?";
Pattern pattern = Pattern.compile(regx,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(txt);
return matcher.find();
}
What about:
Peter Müller
François Hollande
Patrick O'Brian
Silvana Koch-Mehrin
Validating names is a difficult issue, because valid names are not only consisting of the letters A-Z.
At least you should use the Unicode property for letters and add more special characters. A first approach could be e.g.:
String regx = "^[\\p{L} .'-]+$";
\\p{L} is a Unicode Character Property that matches any kind of letter from any language
try this regex (allowing Alphabets, Dots, Spaces):
"^[A-Za-z\s]{1,}[\.]{0,1}[A-Za-z\s]{0,}$" //regular
"^\pL+[\pL\pZ\pP]{0,}$" //unicode
This will also ensure DOT never comes at the start of the name.
For those who use java/android and struggle with this matter try:
"^\\p{L}+[\\p{L}\\p{Z}\\p{P}]{0,}"
This works with names like
José Brasão
You could even try this expression ^[a-zA-Z\\s]*$ for checking a string with only letters and spaces (nothing else).
For me it worked. Hope it works for you as well.
Or go through this piece of code once:
CharSequence inputStr = expression;
Pattern pattern = Pattern.compile(new String ("^[a-zA-Z\\s]*$"));
Matcher matcher = pattern.matcher(inputStr);
if(matcher.matches())
{
//if pattern matches
}
else
{
//if pattern does not matches
}
please try this regex (allow only Alphabets and space)
"[a-zA-Z][a-zA-Z ]*"
if you want it for IOS then,
NSString *yourstring = #"hello";
NSString *Regex = #"[a-zA-Z][a-zA-Z ]*";
NSPredicate *TestResult = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",Regex];
if ([TestResult evaluateWithObject:yourstring] == true)
{
// validation passed
}
else
{
// invalid name
}
Regex pattern for matching only alphabets and white spaces:
String regexUserName = "^[A-Za-z\\s]+$";
Accept only character with space :-
if (!(Pattern.matches("^[\\p{L} .'-]+$", name.getText()))) {
JOptionPane.showMessageDialog(null, "Please enter a valid character", "Error", JOptionPane.ERROR_MESSAGE);
name.setFocusable(true);
}
My personal choice is:
^\p{L}+[\p{L}\p{Pd}\p{Zs}']*\p{L}+$|^\p{L}+$, Where:
^\p{L}+ - It should start with 1 or more letters.
[\p{Pd}\p{Zs}'\p{L}]* - It can have letters, space character (including invisible), dash or hyphen characters and ' in any order 0 or more times.
\p{L}+$ - It should finish with 1 or more letters.
|^\p{L}+$ - Or it just should contain 1 or more letters (It is done to support single letter names).
Support for dots (full stops) was dropped, as in British English it can be dropped in Mr or Mrs, for example.
To validate for only letters and spaces, try this
String name1_exp = "^[a-zA-Z]+[\-'\s]?[a-zA-Z ]+$";
Validates such values as:
"", "FIR", "FIR ", "FIR LAST"
/^[A-z]*$|^[A-z]+\s[A-z]*$/
check this out.
String name validation only accept alphabets and spaces
public static boolean validateLetters(String txt) {
String regx = "^[a-zA-Z\\s]+$";
Pattern pattern = Pattern.compile(regx,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(txt);
return matcher.find();
}
To support language like Hindi which can contain /p{Mark} as well in between language characters.
My solution is ^[\p{L}\p{M}]+([\p{L}\p{Pd}\p{Zs}'.]*[\p{L}\p{M}])+$|^[\p{L}\p{M}]+$
You can find all the test cases for this here
https://regex101.com/r/3XPOea/1/tests
#amal. This code will match your requirement. Only letter and space in between will be allow, no number. The text begin with any letter and could have space in between only. "^" denotes the beginning of the line and "$" denotes end of the line.
public static boolean validateLetters(String txt) {
String regx = "^[a-zA-Z ]+$";
Pattern pattern = Pattern.compile(regx,Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(txt);
return matcher.find();
}
Try with this:
public static boolean userNameValidation(String name){
return name.matches("(?i)(^[a-z])((?![? .,'-]$)[ .]?[a-z]){3,24}$");
}
For Java, you can use below for Name validation which uses Alpha (Letters) + Spaces (Blanks or tabs)
"[^\\\p{Alpha}\\\p{Blank}]"
Can get a reference from Wikipedia for ASCII values also.
I need to check a string whether it includes a specific arrangements of letters and numbers.
Valid arrangements are for example:
X
X-Y
A-H-K-L-J-Y
A-H-J-Y
123
12?
12*
12-17
Invalid are for example:
-X-Y
-XY
*12
?12
I have written this method in java to solve this problem (but i don´t have some experiences with regular expressions):
public boolean checkPatternMatching(String sourceToScan, String searchPattern) {
boolean patternFounded;
if (sourceToScan == null) {
patternFounded = false;
} else {
Pattern pattern = Pattern.compile(Pattern.quote(searchPattern),
Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(sourceToScan);
patternFounded = matcher.find();
}
return patternFounded;
}
How can i implemented this requirement with regular expressions?
By the way: It is a good solution to check a string, whether it includes numeric content by using the method isNumeric from the java class StringUtils?
//EDIT
The link, which was edited by the admins includes not specific arrangements of characters but only an appearance of characters with regular expressions in general !
After a good while trying to help, answering to constantly changing questions, just found out that the same was asked yesterday, and that the OP doesn't accept answers to his questions...all I have left to say is good night sir, good luck
n-th answer follows:
First pattern: [a-z](-[a-z])* : a letter, possibly followed by more letters, separated by -.
Second pattern: \d+(-\d+)*[?*]* : a number, possibly followed by more numbers, separated by -, and possibly ending with ? or *.
So join them together: ^([a-z](-[a-z])*)|(\d+(-\d+)*[?*]*)$. ^ and $ mark the beginning and the end of the string.
Few more comments on the code: you don't need to use Pattern.quote, and you should use matches() instead of find(), because find() returns true if any part of the string matches the pattern, and you want the whole string:
public static boolean checkPatternMatching(String sourceToScan, String searchPattern) {
boolean patternFounded;
if (sourceToScan == null) {
patternFounded = false;
} else {
Pattern pattern = Pattern.compile(searchPattern, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(sourceToScan);
patternFounded = matcher.matches();
}
return patternFounded;
}
Called like this: checkPatternMatching(s, "^([a-z](-[a-z])*)|(\\d+(-\\d+)*[?*]*)$")
About the second question, this is the current implementation of StringUtils.isNumeric:
public static boolean isNumeric(final CharSequence cs) {
if (isEmpty(cs)) {
return false;
}
final int sz = cs.length();
for (int i = 0; i < sz; i++) {
if (Character.isDigit(cs.charAt(i)) == false) {
return false;
}
}
return true;
}
So no, there is nothing wrong about it, that is as simple as it gets. But you need to include an external JAR in your program, which I find unnecessary if you just want to use such a simple method.
I believe that you should first remove the Pattern.quote() method because that would turn the inputting patterns into string literals; and those are not really useful in your context.
To match the valid arrangements with letters, something like this should work:
^[a-z](?:-[a-z])*$
For the numbers (if I understood the rules correctly):
^\\d+(?:[?*]|-\\d+)*$
And if you want to combine them:
^(?:[a-z](?:-[a-z])*|\\d+(?:[?*]|-\\d+)*)$
I'm not familiar with Java itself, nor the isNumeric method, sorry.
As per your comment, if you want to accept *12 or 1?2 or 12*456, you can use:
^\\*?\\d+(?:[?*]\\d*|-\\d+)*$
Then add it to the previous regex like so:
^(?:[a-z](?:-[a-z])*|\\*?\\d+(?:[?*]\\d*|-\\d+)*)$
If I have a key that has the following sequence of characters: _(some number)_1. How can I just return (some number).
For example if the key is _6654_1 I just need value 6654. The problem/issue that's really confusing me is the number could be any length like _9332123425234_1 in which case I would just need the 9332123425234.
Here's what I've tried so far:
Pattern p = Pattern.compile("_[\\d]_1");
Matcher match = p.matcher(request.getParameter("course_id"));
but this won't cover the case where the middle number can be any number (not just four digits) will it?
You could just figure out the indexOf('_') and then use substring. No need for regular expressions.
...but since you asked for regular expressions, here you go:
import java.util.regex.*;
class Test {
public static void main(String[] args) {
String str = "_6654_1";
Pattern p = Pattern.compile("_(\\d+)_1");
Matcher m = p.matcher(str);
if (m.matches())
System.out.println(m.group(1)); // prints 6654
}
}
(And here is the substring-approach for comparison:)
String str = "_6654_1";
String num = str.substring(1, str.indexOf('_', 1));
System.out.println(num); // prints 6654
And, a final solution, using a simple split("_"):
String str = "_6654_1";
System.out.println(str.split("_")[1]); // prints.... you guessed it: 6654
Do you really need regexp? You can use substring and indexOf:
String st = "_9332123425234_1";
String number = st.substring(1,st.indexOf('_',1));
Assuming you have the underscores before and after your digit sequence, you could use _(\d+)_ to create a Capturing Group.
See http://download.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html
You might also want to consider using a Splitter:
Splitter
This might be more efficient than a regex and since it returns all the elements you will be the before and after elements as well as the number in the middle. So, if you eventually need the number after the second "_" this might be the better way to go.