package com.paessler.prtg.util; import java.nio.charset.Charset; import java.text.CharacterIterator; import java.text.StringCharacterIterator; import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.StringTokenizer; import java.util.Vector; /****************************************************************************** * A library of static String utility functions * @author JR Andreassen * @version 1.0 *****************************************************************************/ public abstract class StringUtility { /** Constant for use as prefix for String encoded HEX */ public static final String HEX_STRING_PREFIX = "0x"; /** Constant for use as Blank String */ public static final String BlankString256 = " "; public static final String Hyphen256 = "---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"; public static final String Underscore256 = "_______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________"; public static final String STRING_ALL_TABS = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; /** Constant for use as Blank String */ public static final String BlankString = " "; /** Constant for use as Empty String */ public static final String EmptyString = ""; /** Constant for use as Line Separator */ public static final String LINE_SEPARATOR = System.getProperty(SystemUtility.SYS_PROPERTY_LINE_SEPARATOR); //----------------------------------------------------------- /** Constants for String elements/characters */ public static final String Period = "."; public static final String Comma = ","; public static final String Colon = ":"; public static final String SemiColon = ";"; public static final String CaretSign = "^"; public static final String Quote = "'"; public static final String DoubleQuote = "\""; public static final String QuestionMark = "?".intern(); public static final String Bang = "!".intern(); public static final String AtSign = "@".intern(); public static final String Asterisk = "*".intern(); public static final String HashMark = "#".intern(); public static final String PercentSign = "%".intern(); public static final String DollarSign = "$".intern(); public static final String Tilde = "~".intern(); public static final String Bar = "|".intern(); public static final String Plus = "+".intern(); public static final String Equal = "=".intern(); public static final String Hyphen = "-".intern(); public static final String Underscore = "_".intern(); public static final String ForwardSlash = "/".intern(); public static final String BackSlash = "\\".intern(); // public static final String NewLine = "\n".intern(); public static final String CarriageRet = "\r".intern(); public static final String HorizTab = "\t".intern(); // public static final String VertTab = "\v".intern(); public static final String LeftParen = "(".intern(); public static final String RightParen = ")".intern(); public static final String LeftCurlyBrace = "{".intern(); public static final String RightCurlyBrace= "}".intern(); public static final String LeftSquareBrace= "[".intern(); public static final String RightSquareBrace= "]".intern(); /** String Constant for logical operation : A > B*/ public static final String GreaterThan = ">".intern(); /** String Constant for logical operation : A < B*/ public static final String LessThan = "<".intern(); /** set of characters that are safe to break on when word wrapping */ //public static final String BREAKEABLE_WORDWRAP_CHARS = " \t\n\f\r*-"; /** a string that is unlikely to occur naturally, useful for temporary * replacements in mutilstep operations like variable substitution and optional * removal */ public static final String UNLIKELY_TO_OCCUR_STR = "Q#TGEF@#$!AC!@sdg34-!@#~~24"; /** Constant for use as Invalid poss or not found with indexOf() etc */ public static final int STRING_INVALID_POSSITION = -1; /** Constant for use as Invalid poss or not found with indexOf() etc */ public static final int STRING_COMPARE_MATCH = 0; private static Charset utf8Charset = Charset.forName("UTF-8"); ////////////////////////////////////////////////////////// /** * Determine TermiatorType */ public static boolean isLineTerminatorCRLF() { return (StringUtility.LINE_SEPARATOR.length() == 2); } //--------------------------------------------------------------------------- /** * This method returns a HashSet of Characters with each * unique character from the string represented. */ public static HashSet<?> getUniqueChars(String str) { HashSet<Character> set = new HashSet<Character>(); for( int i=0; i < str.length(); i++ ) { set.add( new Character(str.charAt(i)) ); } return set; }//method // --------------------------------------------------- /* * Strips all the characters in the list from the string. * @param tostrip The string to strip * @param char_set Set of characters to strip. * @return String Stripped string or parameter 'tostrip' **/ public static String stripchars(String tostrip, String char_set) throws Exception { if(tostrip == null || char_set == null) { return tostrip; } StringBuilder retVal = new StringBuilder(); int i = 0; byte[] chars = char_set.getBytes(); CharacterIterator citer = new StringCharacterIterator(tostrip); char curr = CharacterIterator.DONE; if(citer != null) { for(;(curr = citer.current()) != CharacterIterator.DONE;citer.next() ) { for (i = 0; i < chars.length; i++) { if(chars[i] == curr) { curr = CharacterIterator.DONE; break; } } if(curr != CharacterIterator.DONE) { retVal.append(curr); } } } return retVal.toString(); } //--------------------------------------------------------------------------- public static final String stripcharsNoThrow(String tostrip, String char_set) { String retVal = tostrip; try { retVal = stripchars(tostrip, char_set); } catch (Exception ex) { } return retVal; } //--------------------------------------------------------------------------- /** * Convinience method to do replacements ans checks * instances of searchStr with replaceStr in the origStr. */ public static String replace(String src, char oldchar, char newchar) { String retVal = src; if (src != null && src.indexOf(oldchar) != STRING_INVALID_POSSITION) { retVal = src.replace(oldchar, newchar); } return retVal; } /** * same as String.indexOf, but this version is case-insensitive * @param stringToCheck string you want to seach through * @param stringToLookFor the substring you are looking for in the other string */ public static int indexOfCaseInsensitive(String stringToCheck, String stringToLookFor, int fromIndex) { stringToCheck = stringToCheck.toLowerCase(); stringToLookFor = stringToLookFor.toLowerCase(); return stringToCheck.indexOf(stringToLookFor, fromIndex); } /** * Returns a new string that is the result of replacing all * instances of searchStr with replaceStr in the origStr. * @param origStr String to be updated * @param searchStr String to substitute * @param replaceStr String to substitute with. * @return String Substituted string. */ public static String searchReplace(String origStr, String searchStr, String replaceStr) { return searchReplace(origStr, searchStr, replaceStr, true); } //--------------------------------------------------------------------------- /** * Returns a new string that is the result of replacing all * instances of searchStr with replaceStr in the origStr. * @param origStr String to be updated * @param searchStr String to substitute * @param replaceStr String to substitute with. * @param caseSensitive * @return String Substituted string. */ public static String searchReplace(String origStr, String searchStr, String replaceStr, boolean caseSensitive) { if( origStr == null || searchStr == null ) return origStr; if( replaceStr == null ) replaceStr = ""; int begIndex = 0; int endIndex = 0; int searchLength = searchStr.length(); StringBuilder returnString = new StringBuilder(origStr.length() * 2); while( true ) { //find the index of the substring occurence if( caseSensitive ) endIndex = origStr.indexOf(searchStr, begIndex); else endIndex = indexOfCaseInsensitive(origStr, searchStr, begIndex); if( endIndex == STRING_INVALID_POSSITION ) { break; } //append this part to the returnString returnString.append( origStr.substring(begIndex, endIndex) ); //append the replacement string returnString.append(replaceStr); //fix the indeces for the next go begIndex = searchLength + endIndex; }//while //now add the ending on endIndex = origStr.length(); returnString.append( origStr.substring(begIndex, endIndex) ); return returnString.toString(); }//method //////////////////////////////////////////////////////////////////// /** * util method to extract var names from strings * finds the next sequence enclosed by startPatternChar and endPatterChar, and returns the text between them * ex) findVariablePattern("xxx%COMPUTERNAME%xxx", '%', '%', 0) -> "COMPUTERNAME" * returns null when there are no matching patterns, or of the srcString is null */ public static String findVariablePattern(String srcString, char startPatternChar, char endPatterChar, int startIdx) { if( srcString == null ) return null; startIdx = srcString.indexOf(startPatternChar, startIdx); if( startIdx == -1 ) return null; int endIdx = srcString.indexOf(endPatterChar, startIdx+1); if( endIdx == -1 ) return null; String varString = srcString.substring(startIdx+1, endIdx); return varString; }//method /** * finds all instances of the stringToFind and replaces them with an upper case version * the find operation is case-insensitive */ public static String upperCaseAllInstances(String origStr, String stringToFind) { String upperedString = stringToFind.toUpperCase(); String newString = searchReplace(origStr, stringToFind, upperedString, false); return newString; } /** * same as upperCaseAllInstances, but takes a list of strings that you want to be uppercased */ public static String upperCaseAllInstances(String origStr, String listOfStringsToFind, String separatorChar) { String newString = origStr; StringTokenizer st = new StringTokenizer(listOfStringsToFind, separatorChar); while( st.hasMoreTokens() ) { String stringToFind = st.nextToken(); newString = upperCaseAllInstances(newString, stringToFind); } return newString; } //--------------------------------------------------------------------------- /** * This method removes all instances of the strToRemove given from the origStr given * @param origStr String to be updated * @param strToRemove String to remove * @return String Substituted string. */ public static String removeAllInstances(String origStr, String strToRemove) { if( origStr == null ) { return null; } int begIndex = 0; int endIndex = 0; int removeLength = strToRemove.length(); StringBuilder returnString = new StringBuilder(origStr.length() * 2); while( true ) { //find the index of the substring occurence endIndex = origStr.indexOf(strToRemove, begIndex); if( endIndex == STRING_INVALID_POSSITION ) { break; } //append this part to the returnString returnString.append( origStr.substring(begIndex, endIndex) ); //fix the indeces for the next go begIndex = removeLength + endIndex; }//while //now add the ending on endIndex = origStr.length(); returnString.append( origStr.substring(begIndex, endIndex) ); return returnString.toString(); }//method //--------------------------------------------------------------------------- /** * This method returns the number of times the character ch occurs in the src String * @param src String to search * @param ch Character to look for * @return int Number of times the character occurs in the string. */ public static int occurs(String src, char ch) { int retval = 0; if(src != null) { byte theBytes[] = src.getBytes(); for(int i=0; i < theBytes.length; i++) { if(theBytes[i] == ch) { retval++; } } } return retval; } //--------------------------------------------------------------------------- /** * This method returns the number of times the string str occurs in the src String * @param src String to search * @param str String to look for * @return int Number of times the String occurs in the string. */ public static int occurs(String src, String str) { int retVal = 0; if(str.length() < 1) { retVal = 1;} else if(src != null && str != null) { int tofindStrLen = str.length(); int fndIdx = src.indexOf(str); while(fndIdx != STRING_INVALID_POSSITION && src.length() > 0) { src = src.substring(fndIdx+tofindStrLen); retVal++; fndIdx = src.indexOf(str); } } return retVal; } //--------------------------------------------------------------------------- /** * This method returns a String that is the result of replicating the * char ch count times. * @param ch Character to replicate * @param count Number of times to replicate * @return String resulting string */ public static String replicate(char ch, int count) { StringBuilder retval = new StringBuilder(count+1); // for(int i=0; i < count; i++) // { retval.append(ch);} appendChars(retval, ch, count); return retval.toString(); } //--------------------------------------------------------------------------- /** * This method returns a String that is the result of replicating the * char ch count times. * @param buff StringBuilder to use to produce the String * @param ch Character to replicate * @param count Number of times to replicate */ public static void appendChars(StringBuilder buff, char ch, int count) { for(int i=0; i < count; i++) { buff.append(ch); } } //--------------------------------------------------------------------------- /** * This method returns a String of blanks count long * char ch count times. * @param count Number of times to replicate * @return String String of count blanks */ public static String getRepeatedStr(String superstr, char torepeat, int count) { String retVal = null; if( superstr != null && count <= superstr.length() ) { retVal = superstr.substring(0, count);} else { retVal = replicate(torepeat, count);} return retVal; } //--------------------------------------------------------------------------- /** * This method returns a String of blanks count long * char ch count times. * @param count Number of times to replicate * @return String String of count blanks */ public static String getBlanks(int count) { return getRepeatedStr(BlankString256, CharacterUtility.Blank, count); /* if( count > BlankString256.length() ) return replicate(' ', count); return BlankString256.substring(0, count); */ } //--------------------------------------------------------------------------- /** * This method returns a String of blanks count long * char ch count times. * @param count Number of times to replicate * @return String String of count blanks */ public static String getHyphens(int count) { return getRepeatedStr(Hyphen256, CharacterUtility.Hyphen, count); } //--------------------------------------------------------------------------- /** * This method returns a String of blanks count long * char ch count times. * @param count Number of times to replicate * @return String String of count blanks */ public static String getUnderscore(int count) { return getRepeatedStr(Underscore256, CharacterUtility.Underscore, count); } //--------------------------------------------------------------------------- /** * This method returns a String of Tabs count long * char ch count times. * @param count Number of times to replicate * @return String String of count blanks */ public static String getTabs(int count) { return getRepeatedStr(STRING_ALL_TABS, CharacterUtility.HorizTab, count); } //--------------------------------------------------------------------------- /** * Pad a string(at end) to given length. * @param str String to pad. * @param pad Character to pad with * @param count Final legnt after padding * @return String String of count blanks */ public static String padString(String str, char pad, int count) { return padString(str, pad, count, false); } //--------------------------------------------------------------------------- /** * Pad a string to given length. * @param str String to pad. * @param pad Character to pad with * @param count Final legnt after padding * @param prePad if true, pads the beginning of the string instead of the end * @return String String of count blanks */ public static String padString(String str, char pad, int count, boolean prePad) { String retVal = str; if(str == null) { retVal = StringUtility.EmptyString; } int len = count - retVal.length(); if (len > 0) { String padStr = null; if (pad == CharacterUtility.Blank) { padStr = StringUtility.getBlanks(len); } else { padStr = StringUtility.replicate(pad, len); } if( prePad == true ) retVal = padStr + retVal; else retVal = retVal + padStr; }//if return retVal; } //--------------------------------------------------------------------------- /** * This method returns a new String that contains the rightmost * length characters if the origStr String. If the length given is * greater than the length of the origStr, then a copy of the origStr * is returned * @param origStr String to extract from * @param length Number of character from the end. * @return String Extracted string */ public static String right(String origStr, int length) { String retVal = origStr; if( origStr != null ) { if ( origStr.length() > length ) retVal = origStr.substring(origStr.length() - length); } return retVal; } //--------------------------------------------------------------------------- /** * This method returns a new String that contains the leftmostmost * length characters if the origStr String. If the length given is * greater than the length of the origStr, then a copy of the origStr * is returned * @param origStr String to extract from * @param length Number of character from the beginning. * @return String Extracted string */ public static String left(String origStr, int length) { String retVal = origStr; if( origStr != null ) { if( origStr.length() > length ) { retVal = origStr.substring(0, length); } } return retVal; } //--------------------------------------------------------------------------- /** * This method returns a new String that is a substring of the origStr * starting at the offset given and continuing length characters or until * the end of the string is reached. * * @param origStr String to extract from * @param offset Starting point. * @param length Number of character to extract. * @return String Extracted string * @throws IndexOutOfBoundsException if offset DNE in origStr */ public static String substringOffsetLength(String origStr, int offset, int length) { if ( origStr == null ) { throw new IndexOutOfBoundsException("StringUtility.substringOffsetLength - origStr is null"); } int origLength = origStr.length(); int endIndex = offset + length; if ( offset >= origLength ) { throw new IndexOutOfBoundsException("StringUtility.substringOffsetLength - offset >= origLength:" + offset + ">=" +origLength);} if( endIndex > origLength-1 ) { endIndex = origLength-1;} return origStr.substring(offset, endIndex); } //--------------------------------------------------------------------------- /** * This method replaces variables in a string * <PRE> * "abcdefg... <variableName>" * Where variableName is a valid key in a hash table/resource bundle. * </PRE> * @param srcStr Source String * @param prop Property Source * @param startVarToken Start Variable name token * @param endVarToken End Variable name token * @return String String with all substitutions performed. * Note: Variables not found in the property will be eliminated. */ /* public static String performVarSubst(String srcStr, Hashtable props) { return performVarSubst(srcStr, props, CharacterUtility.GreaterThan, CharacterUtility.LessThan); } */ /* public static String performVarSubst(String srcStr, Hashtable props, char startVarToken, char endVarToken) { if (srcStr == null || props == null) { if(Log.DEBUG ) { Log.printDebug("(srcStr=\'"+ srcStr +"\', props) Either srcStr or props is null"); } return null; } int openpos = StringUtility.occurs(srcStr, startVarToken); int closepos= StringUtility.occurs(srcStr, endVarToken); if (openpos != closepos) { if(Log.DEBUG ) { Log.printDebug("("+ srcStr +") missmatched '"+startVarToken+endVarToken+"'"); } return null; } openpos = srcStr.indexOf(startVarToken); if (openpos == STRING_INVALID_POSSITION) { return srcStr; } closepos = STRING_INVALID_POSSITION; String tmpStr = null, varName = null; StringBuilder buf = new StringBuilder(); while(openpos > STRING_INVALID_POSSITION) { buf.append(srcStr.substring(closepos+1, openpos)); closepos= srcStr.indexOf(endVarToken, openpos+1); if(closepos == STRING_INVALID_POSSITION) { break;} varName = srcStr.substring(openpos+1, closepos); if (varName != null) { tmpStr = ObjectUtility.toString(props.get(varName)); } if (tmpStr != null) { buf.append(tmpStr); } openpos = srcStr.indexOf(startVarToken, closepos+1); tmpStr = null; varName = null; } if (closepos+1 < srcStr.length()) { buf.append(srcStr.substring(closepos+1)); } return buf.toString(); } */ //--------------------------------------------------------------------------- // /////////////////////////////////////////////////// // *************************************************** // /////////////////////////////////////////////////// /* public static void main(String[] args) { String testString; // System.err.println("testString->" + testString); // testString = removeOptionals(testString, "{", "}", UNLIKELY_TO_OCCUR_STR); // System.err.println("testString->" + testString); //testString = "{123{56}89}"; //int i = findMatching(testString, 1, "{", "}"); //System.err.println("i->" + i); testString = "This is a \ttest\r"; //System.err.println("testString->" + testString); //testString = testString.replace("#test", "ReplacementStr"); //System.err.println("testString->" + testString); // testString = removeOptionals(testString, "#", "", UNLIKELY_TO_OCCUR_STR); // System.err.println("testString->" + testString); testString = replaceWhiteSpaceChars(testString, "#"); System.err.println("testString->" + testString); System.exit(0); } */ // --------------------------------------------------------------------------- /** * Encode bytes as a hex String * Assumes a prefix of '0x' * @param valarr Byte Array to encode as a Hex String * @param len Length to encode * @return String The encoded string */ public static String toHexString(byte[] valarr) { return toHexString(valarr, valarr.length);} // --------------------------------------------------------------------------- /** * Encode bytes as a hex String * Assumes a prefix of '0x' * @param valarr Byte Array to encode as a Hex String * @param len Length to encode * @return String The encoded string */ public static String toHexString(byte[] valarr, int len) { return toHexString(valarr, 0, len);} // --------------------------------------------------------------------------- /** * Encode bytes as a hex String * Assumes a prefix of '0x' * @param valarr Byte Array to encode as a Hex String * @param len Length to encode * @return String The encoded string */ public static String toHexString(byte[] valarr, int start, int len) { return toHexString(valarr, start, len, "0x");} // --------------------------------------------------------------------------- /** * Encode bytes as a hex String * @param valarr Byte Array to encode as a Hex String * @param len Length to encode * @param prefix Hex String prefix * @return String The encoded string */ public static String toHexString(byte[] valarr, int start, int len, String prefix) { return toHexString(valarr, start, len, prefix, null); } // --------------------------------------------------------------------------- /** * Encode bytes as a hex String * @param valarr Byte Array to encode as a Hex String * @param len Length to encode * @param prefix Hex String prefix * @return String The encoded string */ public static String toHexString(byte[] valarr, int start, int len, String prefix, String separator) { String retVal = null; if (valarr != null && valarr.length > 0) { StringBuilder strBuff = new StringBuilder(prefix); if (len < 0) { len = valarr.length; } for(int i =start ; i < len; i++) { if (separator != null && i > 0) {strBuff.append(separator); } strBuff.append(toHexString(valarr[i], true)); } retVal = strBuff.toString(); } return retVal; } // --------------------------------------------------------------------------- public static String toHexStringOld(byte[] valarr, int len, String prefix) { String retVal = null; byte currByte = 0; if (valarr != null && valarr.length > 0) { StringBuilder strBuff = new StringBuilder(prefix); if (len < 0) { len = valarr.length; } String tmpStr= null; for(int i =0 ; i < len; i++) { currByte = valarr[i]; tmpStr = Integer.toHexString(currByte); if(tmpStr.length() > 2) { tmpStr = tmpStr.substring(tmpStr.length() - 2); } else if(tmpStr.length() == 1) // byte < 16 { strBuff.append(digits[0]); } strBuff.append(tmpStr); } retVal = strBuff.toString(); } return retVal; } // --------------------------------------------------------------------------- /** * Creates a string representation of the integer argument as an * unsigned integer in base 16. * <p> * The unsigned integer value is the argument plus 2<sup>32</sup> if * the argument is negative; otherwise, it is equal to the argument. * This value is converted to a string of ASCII digits in hexadecimal * (base 16) with no extra leading <code>0</code>s. If the * unsigned magnitude is zero, it is represented by a single zero * character <tt>'0'</tt> (<tt>'\u0030'</tt>); otherwise, the first * character of the representation of the unsigned magnitude will * not be the zero character. The following characters are used as * hexadecimal digits: * <blockquote><pre> * 0123456789abcdef * </pre></blockquote> * These are the characters <tt>'\u0030'</tt> through <tt>'\u0039'</tt> * and <tt>'u\0039'</tt> through <tt>'\u0066'</tt>. If the uppercase * letters are desired, the {@link java.lang.String#toUpperCase()} * method may be called on the result: * <blockquote><pre> * Long.toHexString(n).toUpperCase() * </pre></blockquote> * * @param i a byte. * @param len Length of result * @param prepad Prepend with leading Zeros. * @return the string representation of the unsigned integer value * represented by the argument in hexadecimal (base 16). */ public static String toHexString(byte i, boolean prepad) { return toUnsignedString(i, 4, 2, prepad); } // --------------------------------------------------------------------------- public static String toHexString(short i, boolean prepad) { return toUnsignedString(i, 4, 4, prepad); } // --------------------------------------------------------------------------- public static String toHexString(int i, boolean prepad) { return toUnsignedString(i, 4, 8, prepad); } // --------------------------------------------------------------------------- /** * Convert the integer to an unsigned number. */ private static String toUnsignedString(int i, int shift, int len, boolean prepad) { char[] buf = new char[32]; int charPos = 32; int radix = 1 << shift; int mask = radix - 1; do { buf[--charPos] = digits[i & mask]; i >>>= shift; len--; } while (i != 0 && len > 0); // prepad with Zero's while (prepad && len > 0) { buf[--charPos] = digits[0]; len--; } return new String(buf, charPos, (32 - charPos)); } // --------------------------------------------------------------------------- /** * All possible chars for representing a number as a String */ final static char[] digits = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' , 'K' , 'L' , 'M' , 'N' , 'O' , 'P' , 'Q' , 'R' , 'S' , 'T' , 'U' , 'V' , 'W' , 'X' , 'Y' , 'Z' }; // ------------------------------------------------------------------------ /** * This method finds all Strings that match a pattern. * It does the equivalent of key.indexOf(pattern); * @param e Enumeration of strings to search * @param pattern Pattern/substring to look for * @return Vector Vector of keys of the matching elements */ public static Vector<String> findMatching(Enumeration<?> e, String pattern) { Vector<String> retVal = new Vector<String>(); String tmpStr, tmpStrCmp; pattern = pattern.toUpperCase(); while (e.hasMoreElements()) { tmpStr = (String)e.nextElement(); if (tmpStr != null) { tmpStrCmp = tmpStr.toUpperCase(); if (tmpStrCmp.indexOf(pattern) != StringUtility.STRING_INVALID_POSSITION) { retVal.add(tmpStr); // if(Log.DEBUG && myLog != null && myLog.getLevel() > 4) // { myLog.println("StringUtility.findMatching(" + pattern + ") Match =>" + tmpStr); } } } } // while return retVal; } // --------------------------------------------------------------------------- /** * This method finds a string between token's * <PRE> * getStringBetween("....yyyxxxzzz....", 0, "yyy", "zzz"); * Should then return "xxx". * </PRE> * @param srcStr Source String * @param startidx Starting point within string * @param startstr Start token * @param endstr End token * @return String the string between the token's or null */ public static String getStringBetween(String srcStr, int startidx, String startstr, String endstr) { String retVal = null; int beginidx = srcStr.indexOf(startstr, startidx); if(beginidx != -1) { beginidx += startstr.length(); int endidx = srcStr.indexOf(endstr, beginidx); if (endidx != -1) { retVal = srcStr.substring(beginidx, endidx); } } return retVal; } // String tmpstr = StringUtility.getStringBetween("com.ibm.db2.jcc.am.SqlDataException: Error for batch element #677: DB2 SQL Error: SQLCODE=-413, SQLSTATE=22003, SQLERRMC=null, DRIVER=4.11.69", 0, "Error for batch element #", ":"); // --------------------------------------------------------------------------- /** * Make String Lower Case * @param val String to convert to Lower * @return LowerCase string */ public static String toLowerCase(String val) { String retVal = val; if (retVal != null) { retVal = retVal.toLowerCase();} return retVal; } // --------------------------------------------------------------------------- /** * Make String upperCase * @param val String to convert to upper * @return UpperCase string */ public static String toUpperCase(String val) { String retVal = val; if (retVal != null) { retVal = retVal.toUpperCase();} return retVal; } // --------------------------------------------------------------------------- /** * Trim string to size * @param val String to trim * @param maxlen max length * @return UpperCase string */ public static String trim(String val, int maxlen) { String retVal = val; if (retVal != null) { retVal = val.trim(); if(retVal.length() > maxlen) { retVal = retVal.substring(0, maxlen);} } return retVal; } // --------------------------------------------------------------------------- /** * Produce Comma separated string of the elements in the Vector. * @param vect Vector of elements * @return String representation of the list */ public static String toString(List<?> vect) { return toString(vect, ", "); } // --------------------------------------------------------------------------- /** * Produce <separator> separated string of the elements in the Vector. * @param vect Vector of elements. * @param separator Separator String. * @return String representation of the list. */ public static String toString(List<?> vect, String separator) { String retVal = null; if (vect != null && vect.size() > 0) { StringBuilder strBuff = new StringBuilder(); for(int i = 0; i < vect.size(); i++) { // Check need for Separator if( i != 0) { strBuff.append(separator); } strBuff.append(vect.get(i).toString()); } retVal = strBuff.toString(); } return retVal; } /** * returns a separated list, taking care of not including empty or null values * returns null if no items are empty in the list */ public static String toSeparatedList(String separator, String... items) { StringBuilder sb = new StringBuilder(); for( String item : items ) { if( item == null || item.length() == 0 ) continue; if( sb.length() > 0 ) sb.append(separator); sb.append(item); } if( sb.length() == 0 ) return null; return sb.toString(); } /** * Convert to a readable string format by replacing special characters * with constant values, for instance \n becomes [NWLN] * @param str String to convert */ public static String toReadableString(String str) { if( str == null ) return null; return ByteUtility.toReadableString(str.getBytes()); } //-------------------------------------------------------------------------- /** Borrowed from Apache.Commons * <p>Wraps a single line of text, identifying words by <code>' '</code>.</p> * * <p>New lines will be separated by the system property line separator. * Very long words, such as URLs will <i>not</i> be wrapped.</p> * * <p>Leading spaces on a new line are stripped. * Trailing spaces are not stripped.</p> * * <pre> * WordUtils.wrap(null, *) = null * WordUtils.wrap("", *) = "" * </pre> * * @param str the String to be word wrapped, may be null * @param wrapLength the column to wrap the words at, less than 1 is treated as 1 * @return a line with newlines inserted, <code>null</code> if null input */ public static String wrap(String str, int wrapLength) { return wrap(str, wrapLength, null, false); } /** * Borrowed from Apache.Commons * <p>Wraps a single line of text, identifying words by <code>' '</code>.</p> * * <p>Leading spaces on a new line are stripped. * Trailing spaces are not stripped.</p> * * <pre> * WordUtils.wrap(null, *, *, *) = null * WordUtils.wrap("", *, *, *) = "" * </pre> * * @param str the String to be word wrapped, may be null * @param wrapLength the column to wrap the words at, less than 1 is treated as 1 * @param newLineStr the string to insert for a new line, * <code>null</code> uses the system property line separator * @param wrapLongWords true if long words (such as URLs) should be wrapped * @return a line with newlines inserted, <code>null</code> if null input */ public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) { if( str == null ) { return null; } if( newLineStr == null ) { newLineStr = System.getProperty("line.separator"); } if( wrapLength < 1 ) { wrapLength = 1; } int inputLineLength = str.length(); int offset = 0; StringBuilder wrappedLine = new StringBuilder(inputLineLength + 32); while( inputLineLength - offset > wrapLength ) { if( str.charAt(offset) == ' ' ) { offset++; continue; } int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset); if( spaceToWrapAt >= offset ) { // normal case wrappedLine.append(str.substring(offset, spaceToWrapAt)); wrappedLine.append(newLineStr); offset = spaceToWrapAt + 1; } else { // really long word or URL if( wrapLongWords ) { // wrap really long word one line at a time wrappedLine.append(str.substring(offset, wrapLength + offset)); wrappedLine.append(newLineStr); offset += wrapLength; } else { // do not wrap really long word, just extend beyond limit spaceToWrapAt = str.indexOf(' ', wrapLength + offset); if( spaceToWrapAt >= 0 ) { wrappedLine.append(str.substring(offset, spaceToWrapAt)); wrappedLine.append(newLineStr); offset = spaceToWrapAt + 1; } else { wrappedLine.append(str.substring(offset)); offset = inputLineLength; } } } } // Whatever is left in line is short enough to just pass through wrappedLine.append(str.substring(offset)); return wrappedLine.toString(); } //////////////////////////////////////////////////////////////////// /** * returns true iff the string given contains non-alpha numeric characters */ public static boolean containsNonAlphaNumerics(String str) { if( str == null ) return false; char[] chars = str.toCharArray(); int len = chars.length; for( int i=0; i < len; i++ ) { if( !Character.isLetterOrDigit(chars[i]) ) return true; }//for return false; }//method //////////////////////////////////////////////////////////////////// /** * Strips all non alphanumeric characters from the string given * (using Character.isLetterOrDigit) */ public static String stripNonAlphaNumerics(String str) { if( str == null ) return null; char[] chars = str.toCharArray(); int len = chars.length; StringBuilder sb = new StringBuilder(len); for( int i=0; i < len; i++ ) { if( Character.isLetterOrDigit(chars[i]) ) sb.append(chars[i]); }//for return sb.toString(); }//method //////////////////////////////////////////////////////////////////// /** * Strips all non numeric characters from the string given * (using Character.isDigit) */ public static String stripNonNumerics(String str) { if( str == null ) return null; char[] chars = str.toCharArray(); int len = chars.length; StringBuilder sb = new StringBuilder(len); for( int i=0; i < len; i++ ) { if( Character.isDigit(chars[i]) ) sb.append(chars[i]); }//for return sb.toString(); }//method /** * returns a std formatted name string * @param lastFirst if true, will reutrn the name like: LNAME, FNAME MNAME * otherwise the format will be FNAME MNAME LNAME */ public static String makeNameString(String fname, String mname, String lname, boolean lastFirst) { String retVal = null; //fName = ObjectUtility.coalesce(fname, ""); //lname = ObjectUtility.coalesce(lname, ""); if( lastFirst ) { retVal = lname + ", " + fname; if( mname != null && mname.length() > 0 ) retVal += " " + mname; }//if else { retVal = fname; if( mname != null && mname.length() > 0 ) retVal += " " + mname; retVal += " " + lname; }//else return retVal.trim(); }//method //////////////////////////////////////////////////////////////////// /** * replaces all newline characters with the newChar, * all carriege returns are removed */ public static String makeOneLine(String s, char newChar) { if( s == null ) return null; s = s.replace('\n', newChar); s = s.replace('\r', '\u0000'); return s; }//method //////////////////////////////////////////////////////////////////// /** * returns true iff two the strings are equal or both strings are null */ public static boolean isEqual(String s1, String s2) { if( s1 == s2 ) return true; if( s1 == null || s2 == null ) return false; return s1.equals(s2); }//method //////////////////////////////////////////////////////////////////// /** * returns true iff the object passed in is an emptry string * NOTE: will return false if the object is null */ public static boolean isEmptyString(Object o) { return (o instanceof String && o != null && ((String)o).length() == 0 ); }//method //////////////////////////////////////////////////////////////////// /** * returns true if the string passed in is null or is empty or contains only blanks * equivalent to if( s == null || s.trim().length() == 0 ) */ public static boolean isEmptyOrNull(String s) { if( s == null || s.trim().length() == 0 ) return true; return false; }//method //////////////////////////////////////////////////////////////////// /** * returns the trimmed string, or null of the string is null or empty */ public static String getTrimmedString(String s) { if( s == null ) return null; s = s.trim(); if( s.length() == 0 ) return null; return s; }//method //////////////////////////////////////////////////////////////////// /** * returns the revers of the string passed in */ public static String reverse(String s) { if( s == null ) return null; char[] charArr = s.toCharArray(); int len = charArr.length; char[] reversString = new char[len]; int pos = 0; for( int i = len-1; i>=0; i-- ) reversString[pos++] = charArr[i]; return new String(reversString); }//method //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // ------------------------------------------------------------- /** * returns the first non null value or null */ public static String coalesce(String val1, String val2) { String retVal = val1; if(retVal == null) {retVal = val2;} return retVal; } // ------------------------------------------------------------- /** * returns the first non null value or null */ public static String coalesce(String val1, String val2, String val3) { String retVal = val1; if(retVal == null) {retVal = val2;} if(retVal == null) {retVal = val3;} return retVal; } //////////////////////////////////////////////////////////////////// /** * remove preceding chars */ public static String removePrecedingChars(String s, char c) { if ( s == null ) return null; int firstKeepIndex = 0; int stringLen = s.length(); char[] strArr = s.toCharArray(); for( int i=0; i < stringLen; i++ ) { if( strArr[i] == c ) firstKeepIndex++; else break; } String returnString = s; if( firstKeepIndex > 0 ) returnString = s.substring(firstKeepIndex); return returnString; }//method //////////////////////////////////////////////////////////////////// /** * remove trailing chars */ public static String removeTrailingChars(String s, char c) { if ( s == null ) return null; int stringLen = s.length(); int lastIndex = stringLen - 1; int lastKeepIndex = lastIndex; char[] strArr = s.toCharArray(); for( int i = lastIndex; i >= 0; i-- ) { if( strArr[i] == c ) lastKeepIndex--; else break; }//for String returnString = s; if( lastKeepIndex < lastIndex ) returnString = s.substring(0, lastKeepIndex+1); return returnString; }//method //////////////////////////////////////////////////////////////////// /** * returns the bytelength of the string for a UTF-8 encoding. Characters within the ASCII set take up 1 byte in UTF-8, both those beyond can take up more */ public static int getStringByteLengthUTF8(String val) { if( val == null ) return -1; return val.getBytes(utf8Charset).length; }//method //////////////////////////////////////////////////////////////////// /** * replace any non-ascii characters in the string given */ public static String replaceNonASCII(String val, String replacement) { if( val == null ) return val; return val.replaceAll("[^\\p{ASCII}]", replacement); }//method //////////////////////////////////////////////////////////////////// /** * replace any control characters in the string given */ public static String replaceControlChars(String val, String replacement) { if( val == null ) return val; return val.replaceAll("[\\p{Cntrl}]", replacement); }//method //////////////////////////////////////////////////////////////////// /** * replace any control characters in the string given */ public static String replaceWhiteSpaceChars(String val, String replacement) { if( val == null ) return val; return val.replaceAll("[\\p{Space}]", replacement); }//method //////////////////////////////////////////////////////////////////// /** * replaces various smart characters and others with equivalent 'normal characters' * MS-word is bad about using special chars that can mess up XML files and whatnot */ public static String replaceSmartCharacters(String s) { if( s == null ) return s; s = s.replace( (char)145, '\''); s = s.replace( (char)8216, '\''); // left single quote s = s.replace( (char)146, '\''); s = s.replace( (char)8217, '\''); // right single quote s = s.replace( (char)147, '\"'); s = s.replace( (char)148, '\"'); s = s.replace( (char)8220, '\"'); // left double s = s.replace( (char)8221, '\"'); // right double s = s.replace( (char)8211, '-' ); // em dash?? s = s.replace( (char)149, '*' ); // bullet s = s.replace( (char)8226, '*' ); // bullet (one of many) s = s.replace( (char)150, '-' ); return s; }//method //////////////////////////////////////////////////////////////////// /** * strips the string of the outer chars given. Can be used to strip off quotes, brackets, parentheses, etc. * if the string starts and ends with the outerChar substring, the outer instances of the substring will be stripped off * NOTE: this is a one pass, so nested outer values will not strip with a single call. * For example, stripOuterChars("[[raaaa]]", "[", "]") will yield "[raaaa]" */ public static String stripOuterChars(String s, String beginningChars, String endingChars) { if( s.startsWith(beginningChars) && s.endsWith(endingChars) ) { int startIdx = beginningChars.length(); int endIdx = s.length() - endingChars.length(); s = s.substring(startIdx, endIdx); } return s; }//method ////////////////////////////////////////////////////////////////// /** * returns a string in the MLA (Modern Language Association) format for citations. * ie <lname>, <fname> <mname>, <suffix> * * lName is the only required parameter. If the other parameters are empty they will not be included in the return, nor will their formatting */ public static String getPersonNameMLAFormat(String fName, String mName, String lName, String suffix) { if( lName == null ) return null; StringBuilder sb = new StringBuilder(lName); if( fName != null ) { sb.append(", ").append(fName); if( mName != null ) sb.append(" ").append(mName); if( suffix != null ) sb.append(", ").append(suffix); } return sb.toString().trim(); } // **************************************************************** // **************************************************************** // ------------------------------------------------------------- // ------------------------------------------------------------- // ------------------------------------------------------------- // ------------------------------------------------------------- /** **************************************************************** * Compute the distance between two strings. * @param source What to match, source * @param target Strings to match * @return int Distance, lower value is better * ref: http://www.codeproject.com/Questions/419563/Get-the-nearest-Match-of-the-string-in-list-of-str * **************************************************************** */ public static int getLevenshteinDistance(String source, String target) { int n = source.length(); int m = target.length(); // Step 1 if (n == 0) { return m;} if (m == 0) { return n; } int[][] d = new int[n + 1][ m + 1]; // Step 2 for (int i = 0; i <= n; d[i][ 0] = i++) { } for (int j = 0; j <= m; d[0][ j] = j++) { } // Step 3 for (int i = 1; i <= n; i++) { //Step 4 for (int j = 1; j <= m; j++) { // Step 5 int cost = (target.charAt(j - 1) == source.charAt(i - 1)) ? 0 : 1; // Step 6 d[i][j] = Math.min( Math.min(d[i - 1][ j] + 1, d[i][ j - 1] + 1), d[i - 1][ j - 1] + cost); } } // Step 7 return d[n][ m]; } /** **************************************************************** * FInd the closest matched string . * @param source What to match, source * @param targets List of Strings to match * @return int Distance, lower value is better * **************************************************************** */ public static int getClosestLevenshteinDistance(String source, List<String> targets) { int retVal = -1; int closestMatchVal = Integer.MAX_VALUE; int tmpval; int currIdx = 0; for(String curr : targets ) { tmpval = getLevenshteinDistance(source, curr); if(tmpval < closestMatchVal) { closestMatchVal = tmpval; retVal = currIdx; } ++currIdx; } return retVal; } /** * convenience method to compare two objects for equality without the hassle of dealing with nulls * returns true iff both values are null, one == two, one.equals(two), or one.toString().equals(two.toString()) * */ public static boolean equals(Object one, Object two, boolean ignoreCase) { if( one == two ) return true; //since they are not outright equal we know both values aren't null, so if either is null we know they cant be equal if( one == null || two == null ) return false; //assert one != null : "Bad logic in comparison"; //assert two != null : "Bad logic in comparison"; if( one.equals(two) ) return true; String str1 = one.toString(); String str2 = two.toString(); if( ignoreCase ) { if( str1.equalsIgnoreCase(str2) ) return true; } else if( str1.equals(str2) ) return true; return false; } // **************************************************************** // **************************************************************** //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // ------------------------------------------------------------- // ------------------------------------------------------------- // ------------------------------------------------------------- // ------------------------------------------------------------- /*public static void main(String[] chars) { / *String text = "Red"; List<String> strList = new ArrayList<String>(); strList.add("RED_Red"); strList.add("MUL_Multicolored"); System.err.println("matched "+getClosestLevenshteinDistance(text, strList));* / System.err.println("t->" + equals(null, null, true)); System.err.println("f->" + equals(null, 1, true)); System.err.println("f->" + equals(1, null, true)); System.err.println("t->" + equals(1, "1", true)); System.err.println("t->" + equals("a", "A", true)); System.err.println("f->" + equals("a", "A", false)); }*/ } // class