My password condition is, minimum 8 characters, minimum one special character, minimum one numeric
For this I wrote a simple class to verify, but eventually fails.
Any help is highly appreciated.
public class PasswordVerifier {
private static final String SPECIAL_CHARACTERS = "(`~!##$%^&*()_+=-][;'/.,\\<>?|:\"}{)";
public static void main(String... args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
String password = in.readLine();
if(!password.matches("^.*(?=.{8,})(?=.*[0-9])(?=.*[SPECIAL_CHARACTERS]).*$")){
System.out.println("Password does not satisfy compliant");
} else {
System.out.println("Yes.. gets through");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
This might work for your requirement:
private static final String SPECIAL_CHARACTERS = "(`~!##$%^&*()_+=-\\]\\[;'/.,\\<>?|:\"}{)";
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
String password = in.readLine();
if(!password.matches("((?=.*\\d)(?=.*["+SPECIAL_CHARACTERS+"]).{8,})")){
System.out.println("Password does not satisfy compliant");
} else {
System.out.println("Yes.. gets through");
}
} catch (IOException e) {
e.printStackTrace();
}
}
The regex specifies:
Input must contains one digit from 0-9
Must contains one special symbols in the list of SPECIAL_CHARACTERS that you've defined
Length should be at least 8 characters
I would not bother trying to write a regular expression. A r.e. that includes all your conditions and nothing more would be difficult to write, harder to understand, and probably not terribly efficient. Just code your requirements explicitly:
boolean isAcceptablePassword(String pwd) {
boolean numeric = false, special = false;
if (pwd.length() >= 8) {
for (int i = pwd.length() - 1; !numeric && !special && i >= 0; --i) {
char c = pwd.charAt(i);
numeric = numeric || Character.isDigit();
special = special || SPECIAL_CHARACTERS.indexOf(c) >= 0;
}
}
return numeric && special;
}
You cannot have ] or - in the middle if a character class, because they have a meaning for the character class syntax. If you want them in there, they have to be the first two elements in the class, - before ].
Related
I have the reg ex \\(.*?\\) to match what ever inside the parenthesis from my text
e.g. ((a=2 and age IN (15,18,56)) and (b=3 and c=4))
my output should only contain:
a=2 and age IN (15,18,56)
b=3 and c=4
I have tried using negative lookahead, not to match .*(?!IN)\\(.*?\\) but not returning what I expect. Can any body help with where I am going wrong?
You will need to parse nested expressions, and regular expressions alone cannot do that for you. A regular expression will only catch the innermost expressions with \\(([^(]*?)\\)
You can use the Pattern and Matcher classes to code a more complex solution.
Or you can use a parser. For Java, there's ANTL.
I just coded something that might help you:
public class NestedParser {
private final char opening;
private final char closing;
private String str;
private List<String> matches;
private int matchFrom(int beginIndex, boolean matchClosing) {
int i = beginIndex;
while (i < str.length()) {
if (str.charAt(i) == opening) {
i = matchFrom(i + 1, true);
if (i < 0) {
return i;
}
} else if (matchClosing && str.charAt(i) == closing) {
matches.add(str.substring(beginIndex, i));
return i + 1;
} else {
i++;
}
}
return -1;
}
public NestedParser(char opening, char closing) {
this.opening = opening;
this.closing = closing;
}
public List<String> match(String str) {
matches = new ArrayList<>();
if (str != null) {
this.str = str;
matchFrom(0, false);
}
return matches;
}
public static void main(String[] args) {
NestedParser parser = new NestedParser('(', ')');
System.out.println(parser.match(
"((a=2 and age IN (15,18,56)) and (b=3 and c=4))"));
}
}
It's not clear what you want in terms of nested brackets (eg. ((a = 2 and b = 3)): is this valid or not?)
This regex gets you most of the way there:
(\(.*?\)+)
On the input you specified, it matches two groups:
((a=2 and age IN (15,18,56))
(b=3 and c=4)) (notice the double-bracket at the end).
It will return everything, including nested brackets. Another variation will return only singly-bracketed expressions:
(\([^(]*?\))
The easiest way to test this is through Rubular.
Hey I am doing a programming assignment and we have to match parentheses in a String. We have to output an Error message such as the following:
Sample I/O:
Enter a string to test:
( < [ { } ( { > ) ] >
error: '>' does not match with '{'.
I am trying to print this message in my isBalanced() method however it will not print the System.out.println() however it is reaching that code block (otherwise it would never return false) which it is. I think the problem lies in my main method but I have been trying for a while now and I am stumped!
Any help is appreciated.
Thanks,
Kyle.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.EmptyStackException;
import java.util.Stack; //using java's default stack in this case as it has more extraneous error checking
public class Question3 {
private static final String OPEN = "([{<";
private static final String CLOSED = ")]}>";
public static void main(String[] args) throws IOException {
BufferedReader inKb = new BufferedReader(new InputStreamReader(
System.in));
System.out.println("Enter a test string:");
String input = inKb.readLine();
boolean successful = isBalanced(input);
System.out.println(successful);
}
public static void printError(char ch, char expected) {
System.out.println("Error: '" + ch + "' does not match with '"
+ expected + "'");
}
private static boolean isOpen(char bracket) {
return OPEN.indexOf(bracket) >= 0;
}
private static boolean isClosed(char bracket) {
return CLOSED.indexOf(bracket) >= 0;
}
private static boolean matches(char openBracket, char closedBracket) {
return OPEN.indexOf(openBracket) == CLOSED.indexOf(closedBracket);
}
public static boolean isBalanced(String input) {
Stack<Character> stack = new Stack<Character>();
try {
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (isOpen(ch)) {
stack.push(ch);
} else if (isClosed(ch)) {
char corBracket = stack.pop(); // pop corresponding bracket
if (!matches(ch, corBracket)) {
System.out.println("Print Test!"); //Not printing?
return false;
}
}
}
} catch (EmptyStackException ex) {
return false;
}
return stack.isEmpty(); //if stack is empty then the corresponding bracket wasn't found!
}
}
In
if (!matches(ch, corBracket)) {
ch is the closing and corBracket is the opening. You need to reverse them
if (!matches(corBracket, ch)) {
to match the method semantics
private static boolean matches(char openBracket, char closedBracket) {
boolean value = OPEN.indexOf(openBracket) == CLOSED.indexOf(closedBracket);
return value;
}
You use descriptive names in the matches method. You should do the same everywhere else.
This is an example where it would be useful to use a debugger.
Debugging your application with the input ( < ) tells me that !matches(ch, corBracket) is evaluated as false and therefore your if statement is ignored. This leads us to believe that your matches(char, char) method is incorrect.
If you try changing your matches method to the following:
private static boolean matches(char openBracket, char closedBracket) {
int i1 = OPEN.indexOf(openBracket);
int i2 = CLOSED.indexOf(closedBracket);
return (i1 == i2);
}
You will see in your debugger that i1 and i2 are both -1 (the return value of indexOf in the case of no occurrence) and since -1 == -1 evaluates to true, !(-1 == -1) evaluates to false, as expected.
Hope this helps.
You are looking for opening brakets in CLOSED and for closing brackets in OPENED!
you need to change
return OPEN.indexOf(openBracket) == CLOSED.indexOf(closedBracket);
into
return CLOSED.indexOf(openBracket) == OPEN.indexOf(closedBracket);
or just swap the parameters in your call
matches(corBracket, ch)
instead of
matches(ch, corBracket)
debuging into the call that function would have show you that OPEN.indexOf(openBracket) return -1 witch is supicious since you are expecting to find what you are searching for i.e. an index which is greater or equal than 0 and less than OPEN.length()
I have been creating a Java program to encode a message received from the user. Just for some background into how it does this: It is supposed to get the input, split it into characters, then get a set of random numbers from Random.org (true random number generator) equal to the length of the message and then shift the characters of the input by their corresponding shift, or random number, then output the coded message and the shifts. So far I have gotten input, converted it into a string array, checked the quota (Random.org has a quota) and gotten the random numbers. I am getting this error when trying to output the converted shifts (from Strings gotten at the website to ints), I think it is because of a CRLF on the last number (I tried using a regex to fix this, but it didn't work). Here is my code:
public class Encryption_System {
static String originalMessege;
public static void main(String[] args) throws Exception {
System.out.println("Welcome to the encryption system!");
System.out.println("Type your messege below:");
System.out.println("\nHere is your original messege: " + scan() + "\n");
Encrypt code = new Encrypt();
code.Messege(originalMessege);
code.encryptMessege();
}
private static String scan() {
Scanner scan = new Scanner(System.in);
originalMessege = scan.nextLine();
return originalMessege;
}
}
Then there is a second class, where my problem originates. My error comes from the last method (my attempted regex fix is commented out):
public class Encrypt {
private String messege;
private String[] characters;
private URL quotaURL;
private URLConnection conect;
private InputStream quotaInput;
private BufferedReader quotaReader;
private int quota;
private boolean go;
private URL shiftsURL;
private URLConnection conectShifts;
private InputStream shiftsInput;
private BufferedReader shiftsReader;
private int count;
private char[] shifts;
private int[] shiftsInt;
private String shiftsString;
private String[] shiftsStrings;
public void Messege(String x) {
messege = x;
}
private String[] getCharacters() {
characters = messege.split("(?!^)");
return characters;
}
private boolean checkQuota() throws Exception {
quotaURL = new URL("http://www.random.org/quota/?format=plain");
conect = quotaURL.openConnection();
quotaInput = conect.getInputStream();
quotaReader = new BufferedReader(new InputStreamReader(quotaInput));
int quota = Integer.parseInt(quotaReader.readLine());
if (quota >= getCharacters().length)
go = true;
else
go = false;
return go;
}
private char[] Shifts(String[] x1) throws Exception {
String[] messegeArray = x1;
count = 0;
for (int k = 0; k < x1.length; k++) {
if (x1[k].equals(" ")) {
continue;
} else {
count++;
}
}
shifts = new char[count * 3];
if (checkQuota() == true) {
shiftsURL = new URL("http://www.random.org/integers/?num=" + count
+ "&min=1&max=27&col=" + count
+ "&base=10&format=plain&rnd=new");
conectShifts = shiftsURL.openConnection();
shiftsInput = conectShifts.getInputStream();
shiftsReader = new BufferedReader(
new InputStreamReader(shiftsInput));
shiftsReader.read(shifts, 0, count * 3);
}
return shifts;
}
public void encryptMessege() throws Exception {
char[] currentShifts = Shifts(getCharacters());
shiftsString = new String(currentShifts);
// shiftsString.replace("[\t\r\n]", "");
shiftsStrings = shiftsString.split("[( )]");
shiftsInt = new int[shiftsStrings.length];
System.out.println("These are your shifts");
for (int v = 0; v < shiftsInt.length; v++) {
shiftsInt[v] = Integer.parseInt(shiftsStrings[v]);
System.out.println(shiftsInt[v] + " ");
}
}
}
and here is my output:
Welcome to the encryption system!
Type your messege below:
Hello
Here is your original messege: Hello
These are your shifts
3
19
12
3
Exception in thread "main" java.lang.NumberFormatException: For input string: "12
Process completed.
I am just a Java beginner (first year high school comp sci), so thanks for any help!
Your code is failing for me because:
shiftsStrings = shiftsString.split("[( )]");
is not properly splitting the values.
EDIT:
Try This:
public void encryptMessege() throws Exception {
List<Integer> shifts = new ArrayList<Integer>();
StringTokenizer st = new StringTokenizer(new String(Shifts(getCharacters())));
while(st.hasMoreTokens())
{
String token =st.nextToken();
try{
shifts.add(Integer.parseInt(token));
}catch(NumberFormatException e)
{
System.out.println("did not parse: " + token);
}
}
System.out.println("These are your shifts: " + shifts.toString());
}
Note there are a lot of things you should work on in your code.
1) Encapsulating functionality within methods. It gets confusing when you keep all your variables as class level attributes. If you pass them between methods using parameters, you gain easier to read code, and it's easier to test bits of your code.
2) You should start method names with lower case letters. This is common Java coding practice.
If you think it is due to non-number characters in the last number, then before putting it in parseInt use Replace on it with the characters that are non-number (you can use \r, \n and so on too).
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#replace(char, char)
Trim is another useful method, it removes all leading and trailing whitespace.
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim()
The problem seems to be originating from here:
shiftsInt[v]= Integer.parseInt(shiftsStrings[v]);
And this fails when in the for loop value of v reaches 4. Remove the expression from the for loop and see if every string in shiftsStrings can actually be parsed to int. Try executing this:
for(int v = 0; v < shiftsStrings.length; v++ ) {
System.out.println(shiftsStrings[v]);
}
If there is something unexpected in the output, the next step would be to find out (and possibly remove) how that value found its place in the array.
I'd like to do a function which gets a string and in case it has inline comments it removes it. I know it sounds pretty simple but i wanna make sure im doing this right, for example:
private String filterString(String code) {
// lets say code = "some code //comment inside"
// return the string "some code" (without the comment)
}
I thought about 2 ways: feel free to advice otherwise
Iterating the string and finding double inline brackets and using substring method.
regex way.. (im not so sure bout it)
can u tell me what's the best way and show me how it should be done? (please don't advice too advanced solutions)
edited: can this be done somehow with Scanner object? (im using this object anyway)
If you want a more efficient regex to really match all types of comments, use this one :
replaceAll("(?:/\\*(?:[^*]|(?:\\*+[^*/]))*\\*+/)|(?://.*)","");
source : http://ostermiller.org/findcomment.html
EDIT:
Another solution, if you're not sure about using regex is to design a small automata like follows :
public static String removeComments(String code){
final int outsideComment=0;
final int insideLineComment=1;
final int insideblockComment=2;
final int insideblockComment_noNewLineYet=3; // we want to have at least one new line in the result if the block is not inline.
int currentState=outsideComment;
String endResult="";
Scanner s= new Scanner(code);
s.useDelimiter("");
while(s.hasNext()){
String c=s.next();
switch(currentState){
case outsideComment:
if(c.equals("/") && s.hasNext()){
String c2=s.next();
if(c2.equals("/"))
currentState=insideLineComment;
else if(c2.equals("*")){
currentState=insideblockComment_noNewLineYet;
}
else
endResult+=c+c2;
}
else
endResult+=c;
break;
case insideLineComment:
if(c.equals("\n")){
currentState=outsideComment;
endResult+="\n";
}
break;
case insideblockComment_noNewLineYet:
if(c.equals("\n")){
endResult+="\n";
currentState=insideblockComment;
}
case insideblockComment:
while(c.equals("*") && s.hasNext()){
String c2=s.next();
if(c2.equals("/")){
currentState=outsideComment;
break;
}
}
}
}
s.close();
return endResult;
}
The best way to do this is to use regular expressions.
At first to find the /**/ comments and then remove all // commnets. For example:
private String filterString(String code) {
String partialFiltered = code.replaceAll("/\\*.*\\*/", "");
String fullFiltered = partialFiltered.replaceAll("//.*(?=\\n)", "")
}
Just use the replaceAll method from the String class, combined with a simple regular expression. Here's how to do it:
import java.util.*;
import java.lang.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
String s = "private String filterString(String code) {\n" +
" // lets say code = \"some code //comment inside\"\n" +
" // return the string \"some code\" (without the comment)\n}";
s = s.replaceAll("//.*?\n","\n");
System.out.println("s=" + s);
}
}
The key is the line:
s = s.replaceAll("//.*?\n","\n");
The regex //.*?\n matches strings starting with // until the end of the line.
And if you want to see this code in action, go here: http://www.ideone.com/e26Ve
Hope it helps!
To find the substring before a constant substring using a regular expression replacement is a bit much.
You can do it using indexOf() to check for the position of the comment start and substring() to get the first part, something like:
String code = "some code // comment";
int offset = code.indexOf("//");
if (-1 != offset) {
code = code.substring(0, offset);
}
#Christian Hujer has been correctly pointing out that many or all of the solutions posted fail if the comments occur within a string.
#Loïc Gammaitoni suggests that his automata approach could easily be extended to handle that case. Here is that extension.
enum State { outsideComment, insideLineComment, insideblockComment, insideblockComment_noNewLineYet, insideString };
public static String removeComments(String code) {
State state = State.outsideComment;
StringBuilder result = new StringBuilder();
Scanner s = new Scanner(code);
s.useDelimiter("");
while (s.hasNext()) {
String c = s.next();
switch (state) {
case outsideComment:
if (c.equals("/") && s.hasNext()) {
String c2 = s.next();
if (c2.equals("/"))
state = State.insideLineComment;
else if (c2.equals("*")) {
state = State.insideblockComment_noNewLineYet;
} else {
result.append(c).append(c2);
}
} else {
result.append(c);
if (c.equals("\"")) {
state = State.insideString;
}
}
break;
case insideString:
result.append(c);
if (c.equals("\"")) {
state = State.outsideComment;
} else if (c.equals("\\") && s.hasNext()) {
result.append(s.next());
}
break;
case insideLineComment:
if (c.equals("\n")) {
state = State.outsideComment;
result.append("\n");
}
break;
case insideblockComment_noNewLineYet:
if (c.equals("\n")) {
result.append("\n");
state = State.insideblockComment;
}
case insideblockComment:
while (c.equals("*") && s.hasNext()) {
String c2 = s.next();
if (c2.equals("/")) {
state = State.outsideComment;
break;
}
}
}
}
s.close();
return result.toString();
}
I made an open source library (on GitHub) for this purpose , its called CommentRemover you can remove single line and multiple line Java Comments.
It supports remove or NOT remove TODO's.
Also it supports JavaScript , HTML , CSS , Properties , JSP and XML Comments too.
Little code snippet how to use it (There is 2 type usage):
First way InternalPath
public static void main(String[] args) throws CommentRemoverException {
// root dir is: /Users/user/Projects/MyProject
// example for startInternalPath
CommentRemover commentRemover = new CommentRemover.CommentRemoverBuilder()
.removeJava(true) // Remove Java file Comments....
.removeJavaScript(true) // Remove JavaScript file Comments....
.removeJSP(true) // etc.. goes like that
.removeTodos(false) // Do Not Touch Todos (leave them alone)
.removeSingleLines(true) // Remove single line type comments
.removeMultiLines(true) // Remove multiple type comments
.startInternalPath("src.main.app") // Starts from {rootDir}/src/main/app , leave it empty string when you want to start from root dir
.setExcludePackages(new String[]{"src.main.java.app.pattern"}) // Refers to {rootDir}/src/main/java/app/pattern and skips this directory
.build();
CommentProcessor commentProcessor = new CommentProcessor(commentRemover);
commentProcessor.start();
}
Second way ExternalPath
public static void main(String[] args) throws CommentRemoverException {
// example for externalPath
CommentRemover commentRemover = new CommentRemover.CommentRemoverBuilder()
.removeJava(true) // Remove Java file Comments....
.removeJavaScript(true) // Remove JavaScript file Comments....
.removeJSP(true) // etc..
.removeTodos(true) // Remove todos
.removeSingleLines(false) // Do not remove single line type comments
.removeMultiLines(true) // Remove multiple type comments
.startExternalPath("/Users/user/Projects/MyOtherProject")// Give it full path for external directories
.setExcludePackages(new String[]{"src.main.java.model"}) // Refers to /Users/user/Projects/MyOtherProject/src/main/java/model and skips this directory.
.build();
CommentProcessor commentProcessor = new CommentProcessor(commentRemover);
commentProcessor.start();
}
for scanner, use a delimiter,
delimiter example.
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class MainClass {
public static void main(String args[]) throws IOException {
FileWriter fout = new FileWriter("test.txt");
fout.write("2, 3.4, 5,6, 7.4, 9.1, 10.5, done");
fout.close();
FileReader fin = new FileReader("Test.txt");
Scanner src = new Scanner(fin);
// Set delimiters to space and comma.
// ", *" tells Scanner to match a comma and zero or more spaces as
// delimiters.
src.useDelimiter(", *");
// Read and sum numbers.
while (src.hasNext()) {
if (src.hasNextDouble()) {
System.out.println(src.nextDouble());
} else {
break;
}
}
fin.close();
}
}
Use a tokenizer for a normal string
tokenizer:
// start with a String of space-separated words
String tags = "pizza pepperoni food cheese";
// convert each tag to a token
StringTokenizer st = new StringTokenizer(tags," ");
while ( st.hasMoreTokens() )
{
String token = (String)st.nextToken();
System.out.println(token);
}
http://www.devdaily.com/blog/post/java/java-faq-stringtokenizer-example
It will be better if code handles single line comment and multi line comment separately . Any suggestions ?
public class RemovingCommentsFromFile {
public static void main(String[] args) throws IOException {
BufferedReader fin = new BufferedReader(new FileReader("/home/pathtofilewithcomments/File"));
BufferedWriter fout = new BufferedWriter(new FileWriter("/home/result/File1"));
boolean multilinecomment = false;
boolean singlelinecomment = false;
int len,j;
String s = null;
while ((s = fin.readLine()) != null) {
StringBuilder obj = new StringBuilder(s);
len = obj.length();
for (int i = 0; i < len; i++) {
for (j = i; j < len; j++) {
if (obj.charAt(j) == '/' && obj.charAt(j + 1) == '*') {
j += 2;
multilinecomment = true;
continue;
} else if (obj.charAt(j) == '/' && obj.charAt(j + 1) == '/') {
singlelinecomment = true;
j = len;
break;
} else if (obj.charAt(j) == '*' && obj.charAt(j + 1) == '/') {
j += 2;
multilinecomment = false;
break;
} else if (multilinecomment == true)
continue;
else
break;
}
if (j == len)
{
singlelinecomment=false;
break;
}
else
i = j;
System.out.print((char)obj.charAt(i));
fout.write((char)obj.charAt(i));
}
System.out.println();
fout.write((char)10);
}
fin.close();
fout.close();
}
Easy solution that doesn't remove extra parts of code (like those above)
// works for any reader, you can also iterate over list of strings instead
String str="";
String s;
while ((s = reader.readLine()) != null)
{
s=s.replaceAll("//.*","\n");
str+=s;
}
str=str.replaceAll("/\\*.*\\*/"," ");
I have been storing phone numbers as longs and I would like to simply add hyphens when printing the phone number as a string.
I tried using DecimalFormat but that doesn't like the hyphen. Probably because it is meant for formatting decimal numbers and not longs.
long phoneFmt = 123456789L;
DecimalFormat phoneFmt = new DecimalFormat("###-###-####");
System.out.println(phoneFmt.format(phoneNum)); //doesn't work as I had hoped
Ideally, I would like to have parenthesis on the area code too.
new DecimalFormat("(###)-###-####");
What is the correct way to do this?
You can use String.replaceFirst with regex method like
long phoneNum = 123456789L;
System.out.println(String.valueOf(phoneNum).replaceFirst("(\\d{3})(\\d{3})(\\d+)", "($1)-$2-$3"));
To get your desired output:
long phoneFmt = 123456789L;
//get a 12 digits String, filling with left '0' (on the prefix)
DecimalFormat phoneDecimalFmt = new DecimalFormat("0000000000");
String phoneRawString= phoneDecimalFmt.format(phoneFmt);
java.text.MessageFormat phoneMsgFmt=new java.text.MessageFormat("({0})-{1}-{2}");
//suposing a grouping of 3-3-4
String[] phoneNumArr={phoneRawString.substring(0, 3),
phoneRawString.substring(3,6),
phoneRawString.substring(6)};
System.out.println(phoneMsgFmt.format(phoneNumArr));
The result at the Console looks like this:
(012)-345-6789
For storing phone numbers, you should consider using a data type other than numbers.
The easiest way to do this is by using the built in MaskFormatter in the javax.swing.text library.
You can do something like this :
import javax.swing.text.MaskFormatter;
String phoneMask= "###-###-####";
String phoneNumber= "123423452345";
MaskFormatter maskFormatter= new MaskFormatter(phoneMask);
maskFormatter.setValueContainsLiteralCharacters(false);
maskFormatter.valueToString(phoneNumber) ;
If you really need the right way then you can use Google's recently open sourced libphonenumber
You could also use https://github.com/googlei18n/libphonenumber. Here is an example:
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
String s = "18005551234";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(s, Locale.US.getCountry());
String formatted = phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);
Here you can get the library on your classpath: http://mvnrepository.com/artifact/com.googlecode.libphonenumber/libphonenumber
The worst possible solution would be:
StringBuilder sb = new StringBuilder();
long tmp = phoneFmt;
sb.append("(");
sb.append(tmp / 10000000);
tmp = tmp % 10000000;
sb.append(")-");
sb.apppend(tmp / 10000);
tmp = tmp % 10000000;
sb.append("-");
sb.append(tmp);
This is how I ended up doing it:
private String printPhone(Long phoneNum) {
StringBuilder sb = new StringBuilder(15);
StringBuilder temp = new StringBuilder(phoneNum.toString());
while (temp.length() < 10)
temp.insert(0, "0");
char[] chars = temp.toString().toCharArray();
sb.append("(");
for (int i = 0; i < chars.length; i++) {
if (i == 3)
sb.append(") ");
else if (i == 6)
sb.append("-");
sb.append(chars[i]);
}
return sb.toString();
}
I understand that this does not support international numbers, but I'm not writing a "real" application so I'm not concerned about that. I only accept a 10 character long as a phone number. I just wanted to print it with some formatting.
Thanks for the responses.
You can implement your own method to do that for you, I recommend you to use something such as this. Using DecimalFormat and MessageFormat. With this method you can use pretty much whatever you want (String,Integer,Float,Double) and the output will be always right.
import java.text.DecimalFormat;
import java.text.MessageFormat;
/**
* Created by Yamil Garcia Hernandez on 25/4/16.
*/
public class test {
// Constants
public static final DecimalFormat phoneFormatD = new DecimalFormat("0000000000");
public static final MessageFormat phoneFormatM = new MessageFormat("({0}) {1}-{2}");
// Example Method on a Main Class
public static void main(String... args) {
try {
System.out.println(formatPhoneNumber("8091231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("18091231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("451231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("11231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("1231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber("231234"));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber(""));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber(0));
} catch (Exception e) {
e.printStackTrace();
}
try {
System.out.println(formatPhoneNumber(8091231234f));
} catch (Exception e) {
e.printStackTrace();
}
}
// Magic
public static String formatPhoneNumber(Object phone) throws Exception {
double p = 0;
if (phone instanceof String)
p = Double.valueOf((String) phone);
if (phone instanceof Integer)
p = (Integer) phone;
if (phone instanceof Float)
p = (Float) phone;
if (phone instanceof Double)
p = (Double) phone;
if (p == 0 || String.valueOf(p) == "" || String.valueOf(p).length() < 7)
throw new Exception("Paramenter is no valid");
String fot = phoneFormatD.format(p);
String extra = fot.length() > 10 ? fot.substring(0, fot.length() - 10) : "";
fot = fot.length() > 10 ? fot.substring(fot.length() - 10, fot.length()) : fot;
String[] arr = {
(fot.charAt(0) != '0') ? fot.substring(0, 3) : (fot.charAt(1) != '0') ? fot.substring(1, 3) : fot.substring(2, 3),
fot.substring(3, 6),
fot.substring(6)
};
String r = phoneFormatM.format(arr);
r = (r.contains("(0)")) ? r.replace("(0) ", "") : r;
r = (extra != "") ? ("+" + extra + " " + r) : r;
return (r);
}
}
Result will be
(809) 123-1234
+1 (809) 123-1234
(45) 123-1234
(1) 123-1234
123-1234
023-1234
java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at java.lang.Double.valueOf(Double.java:502)
at test.formatPhoneNumber(test.java:66)
at test.main(test.java:45)
java.lang.Exception: Paramenter is no valid
at test.formatPhoneNumber(test.java:78)
at test.main(test.java:50)
(809) 123-1232
DecimalFormat doesn't allow arbitrary text within the number to be formatted, just as a prefix or a suffix. So it won't be able to help you there.
In my opinion, storing a phone number as a numeric value is wrong, entirely. What if I want to store an international number? Many countries use + to indicate a country code (e.g. +1 for USA/Canda), others use 00 (e.g. 001).
Both of those can't really be represented in a numeric data type ("Is that number 1555123 or 001555123?")
You could use the substring and concatenation for easy formatting too.
telephoneNumber = "("+telephoneNumber.substring(0, 3)+")-"+telephoneNumber.substring(3, 6)+"-"+telephoneNumber.substring(6, 10);
But one thing to note is that you must check for the lenght of the telephone number field just to make sure that your formatting is safe.
U can format any string containing non numeric characters also to your desired format use my util class to format
usage is very simple
public static void main(String[] args){
String num = "ab12345*&67890";
System.out.println(PhoneNumberUtil.formateToPhoneNumber(num,"(XXX)-XXX-XXXX",10));
}
output: (123)-456-7890
u can specify any foramt such as XXX-XXX-XXXX and length of the phone number , if input length is greater than specified length then string will be trimmed.
Get my class from here: https://github.com/gajeralalji/PhoneNumberUtil/blob/master/PhoneNumberUtil.java
Pattern phoneNumber = Pattern.compile("(\\d{3})(\\d{3})(\\d{4})");
// ...
Matcher matcher = phoneNumber(numberAsLineOf10Symbols);
if (matcher.matches) {
return "(" + matcher.group(1) + ")-" +matcher.group(2) + "-" + matcher.group(3);
}
I'd have thought you need to use a MessageFormat rather than DecimalFormat. That should be more flexible.
String formatterPhone = String.format("%s-%s-%s", phoneNumber.substring(0, 3), phoneNumber.substring(3, 6), phoneNumber.substring(6, 10));
Using StringBuilder for performance.
long number = 12345678L;
System.out.println(getPhoneFormat(String.valueOf(number)));
public static String getPhoneFormat(String number)
{
if (number == null || number.isEmpty() || number.length() < 6 || number.length() > 15)
{
return number;
}
return new StringBuilder("(").append(number.substring(0, 3))
.append(") ").append(number.substring(3, 6))
.append("-").append(number.substring(6))
.toString();
}
Kotlin
val number = 088899998888
val phone = number.phoneFormatter()
fun String.phoneFormatter(): String { return this.replace("\\B(?=(\\d{4})+(?!\\d))".toRegex(), "-") }
The result will be 0888-9999-8888
I used this one
String columValue = "1234567890
String number = columValue.replaceFirst("(\d{3})(\d{3})(\d+)", "($1) $2-$3");