com.insprise.common.lang.StringUtilities.java Source code

Java tutorial

Introduction

Here is the source code for com.insprise.common.lang.StringUtilities.java

Source

 /**
  * $Id$
  * $License$
  *
  * Created on Oct 30, 2007 4:53:05 PM
  */

 package com.insprise.common.lang;

 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Formatter;
 import java.util.HashMap;
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.StringTokenizer;
 import java.util.regex.Pattern;

 /**
  * String utilities.
  */
 @SuppressWarnings({ "unchecked" })
 public class StringUtilities {
     public static final String[] EMPTY_ARRAY = new String[0];
     /** Formatter with two decimal points, trail zeros will be omitted. */
     public static final DecimalFormat DECIMAL_FORMAT_COMMON = new DecimalFormat("##########.##");

     private static String lineSep;

     /**
      * the line separator for this OS
      * @return
      */
     public static String getLineSeparator() {
         if (lineSep == null) {
             lineSep = System.getProperty("line.separator");
         }
         return lineSep;
     }

     /**
      * Get the line break;
      * @param s
      * @return
      */
     public static String getLineBreak(String s) {
         Object[] results = indexOfLineBreakAnyOs(s, 0);
         if (results != null) {
             return (String) results[1];
         }
         return null;
     }

     /**
      * Finds index of line break (can be '\r', '\n', or '\r\n').
      * @param s string to be searched
      * @param indexStart index to start the search
      * @return an array of two element index (int) and line break separator (string), or <code>null</code> if not found.
      */
     public static Object[] indexOfLineBreakAnyOs(String s, int indexStart) {
         // find line break on any OS win/mac/unix
         for (int b = indexStart; b < s.length(); b++) {
             if (s.charAt(b) == '\n') { // unix
                 return new Object[] { b, "\n" };
             } else if (s.charAt(b) == '\r') { // windows or mac
                 if (b + 1 < s.length() && s.charAt(b + 1) == '\n') { // Windows
                     return new Object[] { b, "\r\n" };
                 } else { // mac
                     return new Object[] { b, "\r" };
                 }
             }
         }
         return null;
     }

private static char[] DIGITS_CHINESE = new char[] {'?', '', '', '', '', '', '', '', '', ''};

     /**
      * Convert all occurrences of  in the string to .
      * @param s
      * @return the string converted.
      */
     public static String convertChineseDigitsToDigits(String s) {
         if (s == null) {
             return null;
         }
         for (int i = 0; i < DIGITS_CHINESE.length; i++) {
             s = s.replace(DIGITS_CHINESE[i], (char) ('0' + i));
         }
         return s;
     }

     private static Map<Character, Character> CHINESE_CHAR_ENG_MAP;

/**
 * Replaces chinese chars into their ASCII counterparts, '??' returns '("23!)'.
 * @param s
 * @return
 */
public static String replaceChineseCharsWithASCII(String s) {
   if(CHINESE_CHAR_ENG_MAP == null) {
      CHINESE_CHAR_ENG_MAP = new HashMap<Character, Character>();
      char[] chars_chinese = new char[] {'?', '', '', '', '', '', '', '', '', '',
            '', '', '?', '', '?',
            '', '', '`', '', '',
            '', '^', '', '', '',
            '', '?', '?', '', '~',
            '', '',
            '', '', '', '', '?', '', '', ''
            };
      char[] chars_english = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
            '.', ',', '`', '?', '!',
            ':', ';', '\'', '`', '"',
            '.', '^', '.', '\'', '\'',
            '"', '"', '"', '"', '~',
            '(', ')',
            '{', '}', '<', '>', '(', ')', '<', '>'
            };
      for (int i = 0; i < chars_chinese.length; i++) {
         CHINESE_CHAR_ENG_MAP.put(chars_chinese[i], chars_english[i]);
      }
   }
   if(s == null) {
      return null;
   }
   StringBuilder sb = null; // created only if there is special Chinese char
   for(int i=0; i < s.length(); i++) {
      char c = s.charAt(i);
      if(c > 0xff) {
         Character eng = CHINESE_CHAR_ENG_MAP.get(c);
         if(eng == null) {
            if(sb != null) {
               sb.append(c);
            }
         }else {
            if(sb == null) {
               sb = new StringBuilder();
               sb.append(s.substring(0, i));
            }
            sb.append(eng);
         }
      }else{
         if(sb != null) {
            sb.append(c);
         }
      }
   }
   return sb == null ? s : sb.toString();
}

     /**
      * Returns true if the given string contains ASCII characters only; false otherwise.
      * @param s
      * @return
      */
     public static boolean containsAsciiCharsOnly(String s) {
         for (int i = 0; s != null && i < s.length(); i++) {
             if (s.charAt(i) > 0x00ff) {
                 return false;
             }
         }
         return true;
     }

     /**
      * Returns true if the given string contains digit numbers only; false otherwise.
      * @param s
      * @return
      */
     public static boolean containsDigitsOnly(String s) {
         for (int i = 0; s != null && i < s.length(); i++) {
             char c = s.charAt(i);
             if (c < '0' || c > '9') {
                 return false;
             }
         }
         return true;
     }

     private static char[] printableAsciiChars = null;

     /**
      * Returns printable ASCII chars (total 126).
      * @return
      */
     public static char[] getPrintableAsciiChars() {
         if (printableAsciiChars == null) {
             StringBuilder sb = new StringBuilder();
             sb.append("0123456789"); // 0-9: 10
             sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); // A-Z: 26
             sb.append("abcdefghijklmnopqrstuvwxyz"); // a-z: 26
             // Ref: http://en.wikipedia.org/wiki/ISO/IEC_8859-1
             for (int i = 0xC0; i <= 0xFF; i++) { //  - : 64
                 sb.append((char) i);
             }
             printableAsciiChars = new char[sb.length()];
             for (int i = 0; i < sb.length(); i++) {
                 printableAsciiChars[i] = sb.charAt(i);
             }
         }
         return printableAsciiChars;
     }

     /**
      * Tokenize the given Java identifier into parts that form it.
      * @param identifier e.g., 'userName' will result ['user', 'Name'].
      * @return
      */
     public static String[] tokenizeIdentifierIntoArray(String identifier) {
         StringBuilder sb = new StringBuilder();
         boolean lastIsUpper = false;
         for (int i = 0; i < identifier.length(); i++) {
             char c = identifier.charAt(i);
             if (i == 0) {
                 sb.append(c);
                 lastIsUpper = Character.isUpperCase(c);
                 continue;
             }

             if (Character.isUpperCase(c)) {
                 if (lastIsUpper) { // HTT
                     // continue of all upper
                 } else { // fileH -> new part.
                     sb.append(";");
                 }
                 sb.append(c);
                 lastIsUpper = true;
             } else {
                 sb.append(c);
                 lastIsUpper = false;
             }
         }

         return tokenizeStringIntoArray(sb.toString(), ";");
     }

     /**
      * Tokenize the given string with the specified delimiter and returns the tokens in an array.
      * @param str the string to be tokenized.
      * @param delimiter the delimiter
      * @return an array containing all the tokens.
      */
     public static String[] tokenizeStringIntoArray(String str, String delimiter) {
         StringTokenizer st = new StringTokenizer(str, delimiter);
         String[] tokens = new String[st.countTokens()];
         int index = 0;
         while (st.hasMoreTokens()) {
             tokens[index++] = st.nextToken().trim();
         }

         return tokens;
     }

     /**
      * Tokenize the given string with the specified delimiter and returns the tokens in a list.
      * @param str the string to be tokenized.
      * @param delimiter the delimiter
      * @return an list containing all the tokens.
      */
     public static List<String> tokenizeStringIntoList(String str, String delimiter) {
         StringTokenizer st = new StringTokenizer(str, delimiter);
         List<String> list = new ArrayList<String>();
         while (st.hasMoreTokens()) {
             list.add(st.nextToken().trim());
         }

         return list;
     }

     /**
      * Capitalize the first letter letter to upper case, no other characters will be changed.
      * @param s the string to be capitalized.
      * @return the string with first letter upper-cased.
      */
     public static String capitalizeWord(String s) {
         if (s == null || s.length() == 0) {
             return s;
         }
         char[] chars = s.toCharArray();
         chars[0] = Character.toUpperCase(chars[0]);
         return new String(chars);
     }

     /**
      * Truncates the given string to the specified length if it is longer than that.
      * @param s
      * @param length
      * @return
      */
     public static String truncate(String s, int length) {
         if (s == null) {
             return s;
         }
         return s.length() > length ? s.substring(0, length) : s;
     }

     /**
      * Abbreviates the given string using ellipses.
      * @param s the string
      * @param maxWidth max number of chars to be shown
      * @return the abbreviated string or <code>null</code> if the given string is <code>null</code>.
      */
     public static String abbreviate(String s, int maxWidth) {
         if (s == null) {
             return null;
         }
         if (maxWidth < 4) {
             throw new IllegalArgumentException("Minimum abbreviation width is 4");
         }
         if (s.length() <= maxWidth) {
             return s;
         }
         return s.substring(0, maxWidth - 3) + "...";
     }

     /**
      * Abbreviates the given string using ellipses on the left side.
      * @param s the string
      * @param maxWidth max number of chars to be shown
      * @return the abbreviated string or <code>null</code> if the given string is <code>null</code>.
      */
     public static String abbreviateLeft(String s, int maxWidth) {
         if (s == null) {
             return null;
         }
         if (maxWidth < 4) {
             throw new IllegalArgumentException("Minimum abbreviation width is 4");
         }
         if (s.length() <= maxWidth) {
             return s;
         }
         return "..." + s.substring(3, 3 + maxWidth);
     }

     /**
      * Counts number of occurrences of the given string.
      * @param sourceString
      * @param lookFor
      * @return
      */
     public static int count(String sourceString, String lookFor) {
         if (sourceString == null || lookFor == null) {
             return 0;
         }
         int count = 0;
         int cursor = 0;
         while ((cursor = sourceString.indexOf(lookFor, cursor)) != -1) {
             cursor += lookFor.length();
             ++count;
         }
         return count;
     }

     private static Hashtable<String, Pattern> compiledPatterns;

     /**
      * Performs regex matche for the given text with optional cache facility.
      * If <code>cacheCompiledPattern</code> is turned on, compiled patterns will be cached and
      * saves compilation time for subsequent usages of the same pattern; otherwise, this method
      * is equivalent to {@linkplain String#matches(String)}.
      * <p>Under normal conditional, the cache should not grow too large. Thus there is no method
      * available to clear the cache for the sake of simplicity. </p>
      * @param pattern the regex pattern.
      * @param text the text to be matched.
      * @param cacheCompiledPattern whether compiled patterns should be cached?
      * @return whether the text matches the pattern.
      */
     public static boolean regexMatch(String pattern, String text, boolean cacheCompiledPattern) {
         if (pattern == null) {
             return false;
         }

         boolean inCache = false;
         Pattern regPattern = null;
         if (compiledPatterns != null) {
             regPattern = compiledPatterns.get(pattern);
         }

         if (regPattern != null) {
             inCache = true;
         } else {
             regPattern = Pattern.compile(pattern);
         }

         if (cacheCompiledPattern && !inCache) {
             if (compiledPatterns == null) {
                 compiledPatterns = new Hashtable<String, Pattern>();
             }
             compiledPatterns.put(pattern, regPattern);
         }

         return regPattern.matcher(text).matches();
     }

     /**
      * Tests whether the two arrays are equal, i.e., all items in an array are contained in the other and vice verse.
      * The orders of items are ignored.
      * This method may not perform well when the array size is large as it uses linear search.
      * @param arrayA
      * @param arrayB
      * @param ignoreCase should the case sensitivity be ignored?
      * @return <code>true</code> if they are equal or <code>false</code> otherwise.
      */
     public static boolean equals(String[] arrayA, String[] arrayB, boolean ignoreCase) {
         if (arrayA == null && arrayB == null) {
             return false;
         }
         if ((arrayA == null && arrayB != null) || (arrayA != null && arrayB == null)) {
             return false;
         }

         // now, both arrayA and arrayB should not be null.

         if (arrayA.length != arrayB.length) {
             return false;
         }

         int[] bits = new int[arrayA.length];

         for (int i = 0; i < arrayB.length; i++) {
             String b = arrayB[i];
             boolean found = false;
             for (int j = 0; j < arrayA.length; j++) {
                 String a = arrayA[j];
                 if (equals(b, a, ignoreCase)) {
                     if (bits[j] == 0) {
                         found = true;
                         bits[j] = 1;
                         break; // the inner for loop.
                     }
                 }
             }

             if (!found) {
                 return false;
             }
         }

         return true;
     }

     /**
      * Tests whether the given string is in the specified string array.
      * @param str the string to be searched.
      * @param strings the string array
      * @param ignoreCase should the case be ignore during search.
      * @return <code>true</code> if the given string is in the array or <code>false</code> otherwise.
      */
     public static boolean contains(String string, String[] strings, boolean ignoreCase) {
         if (strings == null) {
             if (string == null) {
                 return true;
             } else {
                 return false;
             }
         } else { // array not null.
             for (String s : strings) {
                 if (string == null) {
                     if (s == null) {
                         return true;
                     }
                 } else {
                     if (ignoreCase) {
                         if (string.equalsIgnoreCase(s)) {
                             return true;
                         }
                     } else {
                         if (string.equals(s)) {
                             return true;
                         }
                     }
                 }
             } // for each item in the array.

             return false;
         }
     }

     /**
      * Wraps a single line of text.
      * <p>Modified from Jakarta Commons Lang WordUtils.java. Leading spaces on a new line are stripped, while
      * trailing spaces are not. </p>
      * @param string the string to be wrapped.
      * @param wrapLength the length of the column to wrap the string.
      * @param wrapLongWords <code>true</code> if long words should be broken and wrapped; <code>false</code> otherwise.
      * @return an array of lines or <code>null</code> if the string is <code>null</code>.
      */
     public static String[] wrap(String string, int wrapLength, boolean wrapLongWords) {
         if (string == null) {
             return null;
         }
         if (wrapLength < 1) {
             wrapLength = 1;
         }

         int offset = 0;

         List<String> lines = new ArrayList<String>();

         StringBuilder sb = new StringBuilder();

         while ((string.length() - offset) > wrapLength) {
             if (string.charAt(offset) == ' ') {
                 offset++;
                 continue;
             }

             int spaceToWrapAt = string.lastIndexOf(' ', wrapLength + offset);

             if (spaceToWrapAt >= offset) { // normal case.
                 lines.add(string.substring(offset, spaceToWrapAt));
                 offset = spaceToWrapAt + 1;
             } else { // really long word.
                 if (wrapLongWords) { // wrap long word one line at a time.
                     lines.add(string.substring(offset, offset + wrapLength));
                     offset += wrapLength;
                 } else { // do not wrap.
                     spaceToWrapAt = string.indexOf(' ', offset + wrapLength);
                     if (spaceToWrapAt > 0) {
                         lines.add(string.substring(offset, spaceToWrapAt));
                         offset = spaceToWrapAt + 1;
                     } else {
                         lines.add(string.substring(offset));
                         offset = string.length(); // finished.
                     }
                 }
             }
         }

         if (offset < string.length()) { // any left over
             lines.add(string.substring(offset));
         }

         return getStringArray(lines);
     }

     /**
      * Returns a properly formatted string representation of the given table (a list of lists of strings).
      * <p><code><pre>{@code List<List<Object>> lists = new ArrayList<List<Object>>();
      * List<Object> list = new ArrayList<Object>();
      * list.add("ID");
      * list.add("Name");
      * list.add("Remarks");
      * lists.add(list);
      *
      * list = new ArrayList<Object>();
      * list.add("A");
      * list.add("Jack");
      * list.add("Employee group");
      * list.add("8");
      * lists.add(list);
      *
      * System.out.println(StringUtilities.displayTable(lists, true, 10));
      *
      * [Results]
      * +----+------+------------+-------+
      * | ID | Name | Remarks    | Score |
      * +----+------+------------+-------+
      * | A  | Jack | Employee   | 8     |
      * |    |      | group      |       |
      * +----+------+------------+-------+}</pre></code>
      * @param table
      * @param firstRowHeadRead is the first row the head read?
      *          if set to <code>true</code>, a line separator will be inserted after the first line.
      * @param maxColumnLength the max. length of a column. If the data is longer, it will be wrapped.
      * @return a properly formatted string representation of the given table (a list of lists of strings).
      */
     public static String displayTable(List<List<Object>> table, boolean firstRowHeadRead, int maxColumnLength) {
         List<Integer> lengths = new ArrayList<Integer>();

         // first, find column length.
         for (int r = 0; r < table.size(); r++) { // for each row
             for (int c = 0; table.get(r) != null && c < table.get(r).size(); c++) { // for each col
                 String s = null;
                 if (table.get(r).get(c) != null) {
                     s = table.get(r).get(c).toString();
                 }
                 Integer oldLength = null;
                 if (lengths.size() > c) {
                     oldLength = lengths.get(c);
                 } else {
                     lengths.add(null);
                 }

                 if (s != null) {

                     if (oldLength == null) {
                         lengths.set(c, Math.min(s.length(), maxColumnLength));
                     } else {
                         lengths.set(c, Math.min(maxColumnLength, Math.max(s.length(), oldLength)));
                     }
                 } else if (oldLength == null || oldLength == 0) {
                     lengths.set(c, 0);
                 }
             }
         }

         StringBuilder sb = new StringBuilder("\n"); // always starts with a new line to avoid misplacement.
         Formatter formatter = new Formatter(sb);

         // ------ starts print separator line.
         for (int i = 0; i < lengths.size(); i++) {
             sb.append("+-"); // margin is 2.

             int colLength = lengths.get(i);

             for (int j = 0; j < colLength + 1; j++) {
                 sb.append("-");
             }
         }
         sb.append("+");
         // ------ finishes print separator line.

         HashMap<Integer, String[]> wraps = new HashMap<Integer, String[]>(); // used to contain wraps.

         for (int r = 0; r < table.size(); r++) { // for each row
             int rowHeight = 1;
             wraps.clear();

             for (int c = 0; table.get(r) != null && c < table.get(r).size(); c++) { // for each col
                 int colLength = lengths.get(c);
                 if (c == 0) {
                     sb.append("\n"); // first col.
                 }
                 sb.append(c == 0 && (!firstRowHeadRead || (firstRowHeadRead && r != 0)) ? "> " : "| ");
                 String s = null;
                 if (table.get(r).get(c) != null) {
                     s = table.get(r).get(c).toString();
                 }
                 if (s == null) {
                     formatter.format("%-" + colLength + "s", "");
                 } else {
                     if (s.length() > colLength) {
                         String[] wrap = wrap(s, colLength, true);
                         rowHeight = Math.max(rowHeight, wrap.length);
                         wraps.put(c, wrap);

                         formatter.format("%-" + colLength + "s", wrap[0]);
                     } else {
                         formatter.format("%-" + (colLength == 0 ? 1 : colLength) + "s", s);
                     }
                 }

                 sb.append(" "); // margin.
                 if (c == table.get(r).size() - 1) { // last row
                     sb.append("|");
                 }
             }

             for (int k = 1; k < rowHeight; k++) { // rowHeight > 1
                 for (int c = 0; table.get(r) != null && c < table.get(r).size(); c++) { // for each col
                     int colLength = lengths.get(c);
                     if (c == 0) {
                         sb.append("\n"); // first col.
                     }
                     sb.append("| ");
                     String s = null;
                     String[] wrap = wraps.get(c);
                     if (wrap != null && wrap.length > k) {
                         s = wrap[k];
                     }
                     if (s == null) {
                         formatter.format("%-" + (colLength == 0 ? 1 : colLength) + "s", "");
                     } else {
                         formatter.format("%-" + colLength + "s", s);
                     }

                     sb.append(" "); // margin.
                     if (c == table.get(r).size() - 1) { // last row
                         sb.append("|");
                     }
                 }
             } // end for // rowHeight > 1.

             if (firstRowHeadRead && r == 0) {
                 // ------ starts print separator line.
                 sb.append("\n");
                 for (int i = 0; i < lengths.size(); i++) {
                     sb.append("+-"); // margin is 2.

                     int colLength = lengths.get(i);

                     for (int j = 0; j < colLength + 1; j++) {
                         sb.append("-");
                     }
                 }
                 sb.append("+");
                 // ------ finishes print separator line.
             }
         } // end for each row

         // ------ starts print separator line.
         sb.append("\n");
         for (int i = 0; i < lengths.size(); i++) {
             sb.append("+-"); // margin is 2.

             int colLength = lengths.get(i);

             for (int j = 0; j < colLength + 1; j++) {
                 sb.append("-");
             }
         }
         sb.append("+"); // ends
         // ------ finishes print separator line.

         return sb.toString();
     }

     /**
      * Converts the given list of Strings into a String array.
      * If the list is <code>null</code>, it returns <code>null</code>. If the list is empty,
      * it returns an empty array.
      * @param list the list of strings
      * @return a String array or <code>null</code> when the list is <code>null</code>.
      */
     public static String[] getStringArray(List<String> list) {
         if (list == null) {
             return null;
         }
         String[] ss = new String[list.size()];
         list.toArray(ss);
         return ss;
     }

     /**
      * Returns the first non empty string in the given order of the parameters.
      * @param strings the list of string.
      * @return the first non empty string in the given order of the parameters or <code>null</code> if all of them are empty.
      */
     public static String getFirstNonEmptyString(String... strings) {
         for (String s : strings) {
             if (isNotEmpty(s)) {
                 return s;
             }
         }

         return null;
     }

     /**
      * Returns <code>true</code>if the string is not null and with length greater than 0.
      * @param s the string to be tested.
      * @return <code>true</code>if the string is not null and with length greater than 0; <code>false</code> otherwise.
      */
     public static boolean isNotEmpty(String s) {
         return s != null && s.length() > 0;
     }

     /**
      * Returns <code>true</code> if the string is null or its length is 0.
      * @param s the string to be tested.
      * @return <code>true</code> if the string is null or its length is 0, <code>false</code> otherwise.
      */
     public static boolean isEmpty(String s) {
         return s == null || s.length() == 0;
     }

     /**
      * Returns <code>true</code> if the string is null or its length is 0 or its contains spaces chars only.
      * @param s the string to be tested.
      * @return <code>true</code> if the string is null or its length is 0, <code>false</code> otherwise.
      */
     public static boolean isEmptyOrSpace(String s) {
         return s == null || s.length() == 0 || s.trim().length() == 0;
     }

     /**
      * Compares whether the two string equals.
      * Returns <ul><li><code>true</code> if both null;
      * <li><code>false</code> if one of is null;
      * <li><code>s1.equals(s2)</code> if neither is null;
      * </ul>
      * @param s1
      * @param s2
      * @param ignoreCase should the case sensitivity be ignored?
      * @return
      */
     public static boolean equals(String s1, String s2, boolean ignoreCase) {
         if (s1 == null) {
             if (s2 == null) {
                 return true;
             } else {
                 return false;
             }
         } else { // s1 not null
             if (s2 == null) {
                 return false;
             } else {
                 return ignoreCase ? s1.equalsIgnoreCase(s2) : s1.equals(s2);
             }
         }
     }

     /**
      * Prints the string representation of the specified collection to the given string builder.
      * Elements of the collection will be separated by ', '.
      * @param collection the collection to be printed.
      * @param sb the string builder for output.
      */
     public static void printCollection(Collection<?> collection, StringBuilder sb) {
         if (collection == null) {
             sb.append("null");
             return;
         }
         boolean first = true;
         for (Iterator iter = collection.iterator(); iter.hasNext();) {
             Object object = (Object) iter.next();
             if (first) {
                 first = false;
             } else {
                 sb.append(", ");
             }
             sb.append(object);
         }
     }

     /**
      * Checks whether the given string represents an integer.
      * Note it will return false if there are spaces before or after digits.
      * @param str
      * @return
      */
     public static boolean isInteger(String str) {
         return isInteger(str, false);
     }

     /**
      * Checks whether the given string represents an integer.
      * @param str
      * @param trimFirst true to trim the string first.
      * @return
      */
     public static boolean isInteger(String str, boolean trimFirst) {
         if (str == null) {
             return false;
         }
         if (trimFirst) {
             str = str.trim();
         }
         if (str.length() == 0) {
             return false;
         }
         for (int i = 0; i < str.length(); i++) {
             if (!(Character.isDigit(str.charAt(i)) || (i == 0 && (str.charAt(i) == '-') || str.charAt(i) == '+'))) {
                 return false;
             }
         }
         return true;
     }

     /**
      * <p>Checks whether the String a valid Java number. (Source: org.apache.commons.lang.math.NumberUtils)</p>
      * <p>Valid numbers include hexadecimal marked with the <code>0x</code>
      * qualifier, scientific notation and numbers marked with a type
      * qualifier (e.g. 123L).</p>
      * <p><code>Null</code> and empty String will return
      * <code>false</code>.</p>
      * @param str  the <code>String</code> to check
      * @return <code>true</code> if the string is a correctly formatted number
      */
     public static boolean isNumber(String str) {
         if (str == null || str.length() == 0) {
             return false;
         }
         char[] chars = str.toCharArray();
         int sz = chars.length;
         boolean hasExp = false;
         boolean hasDecPoint = false;
         boolean allowSigns = false;
         boolean foundDigit = false;
         // deal with any possible sign up front
         int start = (chars[0] == '-') ? 1 : 0;
         if (sz > start + 1) {
             if (chars[start] == '0' && chars[start + 1] == 'x') {
                 int i = start + 2;
                 if (i == sz) {
                     return false; // str == "0x"
                 }
                 // checking hex (it can't be anything else)
                 for (; i < chars.length; i++) {
                     if ((chars[i] < '0' || chars[i] > '9') && (chars[i] < 'a' || chars[i] > 'f')
                             && (chars[i] < 'A' || chars[i] > 'F')) {
                         return false;
                     }
                 }
                 return true;
             }
         }
         sz--; // don't want to loop to the last char, check it afterwords
               // for type qualifiers
         int i = start;
         // loop to the next to last char or to the last char if we need another digit to
         // make a valid number (e.g. chars[0..5] = "1234E")
         while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
             if (chars[i] >= '0' && chars[i] <= '9') {
                 foundDigit = true;
                 allowSigns = false;

             } else if (chars[i] == '.') {
                 if (hasDecPoint || hasExp) {
                     // two decimal points or dec in exponent
                     return false;
                 }
                 hasDecPoint = true;
             } else if (chars[i] == 'e' || chars[i] == 'E') {
                 // we've already taken care of hex.
                 if (hasExp) {
                     // two E's
                     return false;
                 }
                 if (!foundDigit) {
                     return false;
                 }
                 hasExp = true;
                 allowSigns = true;
             } else if (chars[i] == '+' || chars[i] == '-') {
                 if (!allowSigns) {
                     return false;
                 }
                 allowSigns = false;
                 foundDigit = false; // we need a digit after the E
             } else {
                 return false;
             }
             i++;
         }
         if (i < chars.length) {
             if (chars[i] >= '0' && chars[i] <= '9') {
                 // no type qualifier, OK
                 return true;
             }
             if (chars[i] == 'e' || chars[i] == 'E') {
                 // can't have an E at the last byte
                 return false;
             }
             if (!allowSigns && (chars[i] == 'd' || chars[i] == 'D' || chars[i] == 'f' || chars[i] == 'F')) {
                 return foundDigit;
             }
             if (chars[i] == 'l' || chars[i] == 'L') {
                 // not allowing L with an exponent
                 return foundDigit && !hasExp;
             }
             // last character is illegal
             return false;
         }
         // allowSigns is true iff the val ends in 'E'
         // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
         return !allowSigns && foundDigit;
     }

     private static Pattern patternEmailAddr = null;

     /**
      * Checks whether the given string represents a valid email address.
      * @param s
      * @return
      */
     public static boolean isEmailAddr(String s) {
         if (s == null) {
             return false;
         }
         if (patternEmailAddr == null) {
             patternEmailAddr = Pattern.compile("[\\w\\.%\\+-]+@[\\w\\.%\\+-]+\\.[A-Za-z]+");
         }
         return patternEmailAddr.matcher(s).matches();
     }

     // ------------ Copied from Commons Language (v2.3) RandomStringUtilities  -----------------------------------------

     /**
      * Creates a random string with the given lenght (count) using the set of chars.
      */
     public static String randomString(int count, char[] chars) {
         return randomString(count, 0, chars.length - 1, true, true, chars);
     }

     /**
      * <p>Creates a random string whose length is the number of characters
      * specified.</p>
      *
      * <p>Characters will be chosen from the set of characters whose
      * ASCII value is between <code>32</code> and <code>126</code> (inclusive).</p>
      *
      * @param count  the length of random string to create
      * @return the random string
      */
     public static String randomAscii(int count) {
         return randomString(count, 32, 127, false, false, null);
     }

     /**
      * <p>Creates a random string whose length is the number of characters
      * specified.</p>
      *
      * <p>Characters will be chosen from the set of alphabetic
      * characters.</p>
      *
      * @param count  the length of random string to create
      * @return the random string
      */
     public static String randomAlphabetic(int count) {
         return randomString(count, 0, 0, true, false, null);
     }

     /**
      * <p>Creates a random string whose length is the number of characters
      * specified.</p>
      *
      * <p>Characters will be chosen from the set of alpha-numeric
      * characters.</p>
      *
      * @param count  the length of random string to create
      * @return the random string
      */
     public static String randomAlphanumeric(int count) {
         return randomString(count, 0, 0, true, true, null);
     }

     /**
      * <p>Creates a random string whose length is the number of characters
      * specified.</p>
      *
      * <p>Characters will be chosen from the set of numeric
      * characters.</p>
      *
      * @param count  the length of random string to create
      * @return the random string
      */
     public static String randomNumeric(int count) {
         return randomString(count, 0, 0, false, true, null);
     }

     /**
      * <p>Random object used by random method. This has to be not local
      * to the random method so as to not return the same value in the
      * same millisecond.</p>
      */
     private static final Random RANDOM = new Random();

     /**
      * <p>Creates a random string based on a variety of options, using
      * supplied source of randomness.</p>
      *
      * <p>If start and end are both <code>0</code>, start and end are set
      * to <code>' '</code> and <code>'z'</code>, the ASCII printable
      * characters, will be used, unless letters and numbers are both
      * <code>false</code>, in which case, start and end are set to
      * <code>0</code> and <code>Integer.MAX_VALUE</code>.
      *
      * <p>If set is not <code>null</code>, characters between start and
      * end are chosen.</p>
      *
      * <p>This method accepts a user-supplied {@link Random}
      * instance to use as a source of randomness. By seeding a single
      * {@link Random} instance with a fixed seed and using it for each call,
      * the same random sequence of strings can be generated repeatedly
      * and predictably.</p>
      *
      * @param count  the length of random string to create
      * @param start  the position in set of chars to start at
      * @param end  the position in set of chars to end before
      * @param letters  only allow letters?
      * @param numbers  only allow numbers?
      * @param chars  the set of chars to choose randoms from.
      *  If <code>null</code>, then it will use the set of all chars.
      * @param random  a source of randomness.
      * @return the random string
      * @throws ArrayIndexOutOfBoundsException if there are not
      *  <code>(end - start) + 1</code> characters in the set array.
      * @throws IllegalArgumentException if <code>count</code> &lt; 0.
      * @since 2.0
      */
     public static String randomString(int count, int start, int end, boolean letters, boolean numbers,
             char[] chars) {
         Random random = RANDOM; // random instance.
         if (count == 0) {
             return "";
         } else if (count < 0) {
             throw new IllegalArgumentException("Requested random string length " + count + " is less than 0.");
         }
         if ((start == 0) && (end == 0)) {
             end = 'z' + 1;
             start = ' ';
             if (!letters && !numbers) {
                 start = 0;
                 end = Integer.MAX_VALUE;
             }
         }

         char[] buffer = new char[count];
         int gap = end - start;

         while (count-- != 0) {
             char ch;
             if (chars == null) {
                 ch = (char) (random.nextInt(gap) + start);
             } else {
                 ch = chars[random.nextInt(gap) + start];
             }
             if ((letters && Character.isLetter(ch)) || (numbers && Character.isDigit(ch))
                     || (!letters && !numbers)) {
                 if (ch >= 56320 && ch <= 57343) {
                     if (count == 0) {
                         count++;
                     } else {
                         // low surrogate, insert high surrogate after putting it in
                         buffer[count] = ch;
                         count--;
                         buffer[count] = (char) (55296 + random.nextInt(128));
                     }
                 } else if (ch >= 55296 && ch <= 56191) {
                     if (count == 0) {
                         count++;
                     } else {
                         // high surrogate, insert low surrogate before putting it in
                         buffer[count] = (char) (56320 + random.nextInt(128));
                         count--;
                         buffer[count] = ch;
                     }
                 } else if (ch >= 56192 && ch <= 56319) {
                     // private high surrogate, no effing clue, so skip it
                     count++;
                 } else {
                     buffer[count] = ch;
                 }
             } else {
                 count++;
             }
         }
         return new String(buffer);
     }

     /**
      * Remove all spaces in a word
      * @param word
      * @return parsed word
      */
     public static String removeWordSpace(String word) {
         StringBuilder sb = new StringBuilder("");
         int len = word.length();
         for (int i = 0; i < len; i++) {
             Character c = word.charAt(i);
             if (!Character.isSpaceChar(c)) {
                 sb.append(c);
             }
         }
         return sb.toString();
     }

 }