001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.lang3; 018 019 /** 020 * <p>Operations on <code>CharSet</code>s.</p> 021 * 022 * <p>This class handles <code>null</code> input gracefully. 023 * An exception will not be thrown for a <code>null</code> input. 024 * Each method documents its behaviour in more detail.</p> 025 * 026 * <p>#ThreadSafe#</p> 027 * @see CharSet 028 * @author Apache Software Foundation 029 * @author Phil Steitz 030 * @author Gary Gregory 031 * @since 1.0 032 * @version $Id: CharSetUtils.java 918868 2010-03-04 06:22:16Z bayard $ 033 */ 034 public class CharSetUtils { 035 036 /** 037 * <p>CharSetUtils instances should NOT be constructed in standard programming. 038 * Instead, the class should be used as <code>CharSetUtils.evaluateSet(null);</code>.</p> 039 * 040 * <p>This constructor is public to permit tools that require a JavaBean instance 041 * to operate.</p> 042 */ 043 public CharSetUtils() { 044 super(); 045 } 046 047 // Squeeze 048 //----------------------------------------------------------------------- 049 /** 050 * <p>Squeezes any repetitions of a character that is mentioned in the 051 * supplied set.</p> 052 * 053 * <pre> 054 * CharSetUtils.squeeze(null, *) = null 055 * CharSetUtils.squeeze("", *) = "" 056 * CharSetUtils.squeeze(*, null) = * 057 * CharSetUtils.squeeze(*, "") = * 058 * CharSetUtils.squeeze("hello", "k-p") = "helo" 059 * CharSetUtils.squeeze("hello", "a-e") = "hello" 060 * </pre> 061 * 062 * @see CharSet#getInstance(java.lang.String) for set-syntax. 063 * @param str the string to squeeze, may be null 064 * @param set the character set to use for manipulation, may be null 065 * @return modified String, <code>null</code> if null string input 066 */ 067 public static String squeeze(String str, String set) { 068 if (StringUtils.isEmpty(str) || StringUtils.isEmpty(set)) { 069 return str; 070 } 071 String[] strs = new String[1]; 072 strs[0] = set; 073 return squeeze(str, strs); 074 } 075 076 /** 077 * <p>Squeezes any repetitions of a character that is mentioned in the 078 * supplied set.</p> 079 * 080 * <p>An example is:</p> 081 * <ul> 082 * <li>squeeze("hello", {"el"}) => "helo"</li> 083 * </ul> 084 * 085 * @see CharSet#getInstance(java.lang.String) for set-syntax. 086 * @param str the string to squeeze, may be null 087 * @param set the character set to use for manipulation, may be null 088 * @return modified String, <code>null</code> if null string input 089 */ 090 public static String squeeze(String str, String[] set) { 091 if (StringUtils.isEmpty(str) || ArrayUtils.isEmpty(set)) { 092 return str; 093 } 094 CharSet chars = CharSet.getInstance(set); 095 StringBuilder buffer = new StringBuilder(str.length()); 096 char[] chrs = str.toCharArray(); 097 int sz = chrs.length; 098 char lastChar = ' '; 099 char ch = ' '; 100 for (int i = 0; i < sz; i++) { 101 ch = chrs[i]; 102 if (chars.contains(ch)) { 103 if ((ch == lastChar) && (i != 0)) { 104 continue; 105 } 106 } 107 buffer.append(ch); 108 lastChar = ch; 109 } 110 return buffer.toString(); 111 } 112 113 // Count 114 //----------------------------------------------------------------------- 115 /** 116 * <p>Takes an argument in set-syntax, see evaluateSet, 117 * and returns the number of characters present in the specified string.</p> 118 * 119 * <pre> 120 * CharSetUtils.count(null, *) = 0 121 * CharSetUtils.count("", *) = 0 122 * CharSetUtils.count(*, null) = 0 123 * CharSetUtils.count(*, "") = 0 124 * CharSetUtils.count("hello", "k-p") = 3 125 * CharSetUtils.count("hello", "a-e") = 1 126 * </pre> 127 * 128 * @see CharSet#getInstance(java.lang.String) for set-syntax. 129 * @param str String to count characters in, may be null 130 * @param set String set of characters to count, may be null 131 * @return character count, zero if null string input 132 */ 133 public static int count(String str, String set) { 134 if (StringUtils.isEmpty(str) || StringUtils.isEmpty(set)) { 135 return 0; 136 } 137 String[] strs = new String[1]; 138 strs[0] = set; 139 return count(str, strs); 140 } 141 142 /** 143 * <p>Takes an argument in set-syntax, see evaluateSet, 144 * and returns the number of characters present in the specified string.</p> 145 * 146 * <p>An example would be:</p> 147 * <ul> 148 * <li>count("hello", {"c-f", "o"}) returns 2.</li> 149 * </ul> 150 * 151 * @see CharSet#getInstance(java.lang.String) for set-syntax. 152 * @param str String to count characters in, may be null 153 * @param set String[] set of characters to count, may be null 154 * @return character count, zero if null string input 155 */ 156 public static int count(String str, String[] set) { 157 if (StringUtils.isEmpty(str) || ArrayUtils.isEmpty(set)) { 158 return 0; 159 } 160 CharSet chars = CharSet.getInstance(set); 161 int count = 0; 162 char[] chrs = str.toCharArray(); 163 int sz = chrs.length; 164 for(int i=0; i<sz; i++) { 165 if(chars.contains(chrs[i])) { 166 count++; 167 } 168 } 169 return count; 170 } 171 172 // Keep 173 //----------------------------------------------------------------------- 174 /** 175 * <p>Takes an argument in set-syntax, see evaluateSet, 176 * and keeps any of characters present in the specified string.</p> 177 * 178 * <pre> 179 * CharSetUtils.keep(null, *) = null 180 * CharSetUtils.keep("", *) = "" 181 * CharSetUtils.keep(*, null) = "" 182 * CharSetUtils.keep(*, "") = "" 183 * CharSetUtils.keep("hello", "hl") = "hll" 184 * CharSetUtils.keep("hello", "le") = "ell" 185 * </pre> 186 * 187 * @see CharSet#getInstance(java.lang.String) for set-syntax. 188 * @param str String to keep characters from, may be null 189 * @param set String set of characters to keep, may be null 190 * @return modified String, <code>null</code> if null string input 191 * @since 2.0 192 */ 193 public static String keep(String str, String set) { 194 if (str == null) { 195 return null; 196 } 197 if (str.length() == 0 || StringUtils.isEmpty(set)) { 198 return ""; 199 } 200 String[] strs = new String[1]; 201 strs[0] = set; 202 return keep(str, strs); 203 } 204 205 /** 206 * <p>Takes an argument in set-syntax, see evaluateSet, 207 * and keeps any of characters present in the specified string.</p> 208 * 209 * <p>An example would be:</p> 210 * <ul> 211 * <li>keep("hello", {"c-f", "o"}) 212 * returns "eo"</li> 213 * </ul> 214 * 215 * @see CharSet#getInstance(java.lang.String) for set-syntax. 216 * @param str String to keep characters from, may be null 217 * @param set String[] set of characters to keep, may be null 218 * @return modified String, <code>null</code> if null string input 219 * @since 2.0 220 */ 221 public static String keep(String str, String[] set) { 222 if (str == null) { 223 return null; 224 } 225 if (str.length() == 0 || ArrayUtils.isEmpty(set)) { 226 return ""; 227 } 228 return modify(str, set, true); 229 } 230 231 // Delete 232 //----------------------------------------------------------------------- 233 /** 234 * <p>Takes an argument in set-syntax, see evaluateSet, 235 * and deletes any of characters present in the specified string.</p> 236 * 237 * <pre> 238 * CharSetUtils.delete(null, *) = null 239 * CharSetUtils.delete("", *) = "" 240 * CharSetUtils.delete(*, null) = * 241 * CharSetUtils.delete(*, "") = * 242 * CharSetUtils.delete("hello", "hl") = "eo" 243 * CharSetUtils.delete("hello", "le") = "ho" 244 * </pre> 245 * 246 * @see CharSet#getInstance(java.lang.String) for set-syntax. 247 * @param str String to delete characters from, may be null 248 * @param set String set of characters to delete, may be null 249 * @return modified String, <code>null</code> if null string input 250 */ 251 public static String delete(String str, String set) { 252 if (StringUtils.isEmpty(str) || StringUtils.isEmpty(set)) { 253 return str; 254 } 255 String[] strs = new String[1]; 256 strs[0] = set; 257 return delete(str, strs); 258 } 259 260 /** 261 * <p>Takes an argument in set-syntax, see evaluateSet, 262 * and deletes any of characters present in the specified string.</p> 263 * 264 * <p>An example would be:</p> 265 * <ul> 266 * <li>delete("hello", {"c-f", "o"}) returns 267 * "hll"</li> 268 * </ul> 269 * 270 * @see CharSet#getInstance(java.lang.String) for set-syntax. 271 * @param str String to delete characters from, may be null 272 * @param set String[] set of characters to delete, may be null 273 * @return modified String, <code>null</code> if null string input 274 */ 275 public static String delete(String str, String[] set) { 276 if (StringUtils.isEmpty(str) || ArrayUtils.isEmpty(set)) { 277 return str; 278 } 279 return modify(str, set, false); 280 } 281 282 //----------------------------------------------------------------------- 283 /** 284 * Implementation of delete and keep 285 * 286 * @param str String to modify characters within 287 * @param set String[] set of characters to modify 288 * @param expect whether to evaluate on match, or non-match 289 * @return modified String 290 */ 291 private static String modify(String str, String[] set, boolean expect) { 292 CharSet chars = CharSet.getInstance(set); 293 StringBuilder buffer = new StringBuilder(str.length()); 294 char[] chrs = str.toCharArray(); 295 int sz = chrs.length; 296 for(int i=0; i<sz; i++) { 297 if(chars.contains(chrs[i]) == expect) { 298 buffer.append(chrs[i]); 299 } 300 } 301 return buffer.toString(); 302 } 303 304 }