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.lang; 018 019 /** 020 * <p>Operations on char primitives and Character objects.</p> 021 * 022 * <p>This class tries to handle <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 * @author Apache Software Foundation 027 * @since 2.1 028 * @version $Id: CharUtils.java 905636 2010-02-02 14:03:32Z niallp $ 029 */ 030 public class CharUtils { 031 032 private static final String CHAR_STRING = 033 "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007" + 034 "\b\t\n\u000b\f\r\u000e\u000f" + 035 "\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017" + 036 "\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f" + 037 "\u0020\u0021\"\u0023\u0024\u0025\u0026\u0027" + 038 "\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f" + 039 "\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037" + 040 "\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f" + 041 "\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047" + 042 "\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f" + 043 "\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057" + 044 "\u0058\u0059\u005a\u005b\\\u005d\u005e\u005f" + 045 "\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067" + 046 "\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f" + 047 "\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077" + 048 "\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u007f"; 049 050 private static final String[] CHAR_STRING_ARRAY = new String[128]; 051 private static final Character[] CHAR_ARRAY = new Character[128]; 052 053 /** 054 * <code>\u000a</code> linefeed LF ('\n'). 055 * 056 * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences 057 * for Character and String Literals</a> 058 * @since 2.2 059 */ 060 public static final char LF = '\n'; 061 062 /** 063 * <code>\u000d</code> carriage return CR ('\r'). 064 * 065 * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences 066 * for Character and String Literals</a> 067 * @since 2.2 068 */ 069 public static final char CR = '\r'; 070 071 072 static { 073 for (int i = 127; i >= 0; i--) { 074 CHAR_STRING_ARRAY[i] = CHAR_STRING.substring(i, i + 1); 075 CHAR_ARRAY[i] = new Character((char) i); 076 } 077 } 078 079 /** 080 * <p><code>CharUtils</code> instances should NOT be constructed in standard programming. 081 * Instead, the class should be used as <code>CharUtils.toString('c');</code>.</p> 082 * 083 * <p>This constructor is public to permit tools that require a JavaBean instance 084 * to operate.</p> 085 */ 086 public CharUtils() { 087 super(); 088 } 089 090 //----------------------------------------------------------------------- 091 /** 092 * <p>Converts the character to a Character.</p> 093 * 094 * <p>For ASCII 7 bit characters, this uses a cache that will return the 095 * same Character object each time.</p> 096 * 097 * <pre> 098 * CharUtils.toCharacterObject(' ') = ' ' 099 * CharUtils.toCharacterObject('A') = 'A' 100 * </pre> 101 * 102 * @param ch the character to convert 103 * @return a Character of the specified character 104 */ 105 public static Character toCharacterObject(char ch) { 106 if (ch < CHAR_ARRAY.length) { 107 return CHAR_ARRAY[ch]; 108 } 109 return new Character(ch); 110 } 111 112 /** 113 * <p>Converts the String to a Character using the first character, returning 114 * null for empty Strings.</p> 115 * 116 * <p>For ASCII 7 bit characters, this uses a cache that will return the 117 * same Character object each time.</p> 118 * 119 * <pre> 120 * CharUtils.toCharacterObject(null) = null 121 * CharUtils.toCharacterObject("") = null 122 * CharUtils.toCharacterObject("A") = 'A' 123 * CharUtils.toCharacterObject("BA") = 'B' 124 * </pre> 125 * 126 * @param str the character to convert 127 * @return the Character value of the first letter of the String 128 */ 129 public static Character toCharacterObject(String str) { 130 if (StringUtils.isEmpty(str)) { 131 return null; 132 } 133 return toCharacterObject(str.charAt(0)); 134 } 135 136 //----------------------------------------------------------------------- 137 /** 138 * <p>Converts the Character to a char throwing an exception for <code>null</code>.</p> 139 * 140 * <pre> 141 * CharUtils.toChar(null) = IllegalArgumentException 142 * CharUtils.toChar(' ') = ' ' 143 * CharUtils.toChar('A') = 'A' 144 * </pre> 145 * 146 * @param ch the character to convert 147 * @return the char value of the Character 148 * @throws IllegalArgumentException if the Character is null 149 */ 150 public static char toChar(Character ch) { 151 if (ch == null) { 152 throw new IllegalArgumentException("The Character must not be null"); 153 } 154 return ch.charValue(); 155 } 156 157 /** 158 * <p>Converts the Character to a char handling <code>null</code>.</p> 159 * 160 * <pre> 161 * CharUtils.toChar(null, 'X') = 'X' 162 * CharUtils.toChar(' ', 'X') = ' ' 163 * CharUtils.toChar('A', 'X') = 'A' 164 * </pre> 165 * 166 * @param ch the character to convert 167 * @param defaultValue the value to use if the Character is null 168 * @return the char value of the Character or the default if null 169 */ 170 public static char toChar(Character ch, char defaultValue) { 171 if (ch == null) { 172 return defaultValue; 173 } 174 return ch.charValue(); 175 } 176 177 //----------------------------------------------------------------------- 178 /** 179 * <p>Converts the String to a char using the first character, throwing 180 * an exception on empty Strings.</p> 181 * 182 * <pre> 183 * CharUtils.toChar(null) = IllegalArgumentException 184 * CharUtils.toChar("") = IllegalArgumentException 185 * CharUtils.toChar("A") = 'A' 186 * CharUtils.toChar("BA") = 'B' 187 * </pre> 188 * 189 * @param str the character to convert 190 * @return the char value of the first letter of the String 191 * @throws IllegalArgumentException if the String is empty 192 */ 193 public static char toChar(String str) { 194 if (StringUtils.isEmpty(str)) { 195 throw new IllegalArgumentException("The String must not be empty"); 196 } 197 return str.charAt(0); 198 } 199 200 /** 201 * <p>Converts the String to a char using the first character, defaulting 202 * the value on empty Strings.</p> 203 * 204 * <pre> 205 * CharUtils.toChar(null, 'X') = 'X' 206 * CharUtils.toChar("", 'X') = 'X' 207 * CharUtils.toChar("A", 'X') = 'A' 208 * CharUtils.toChar("BA", 'X') = 'B' 209 * </pre> 210 * 211 * @param str the character to convert 212 * @param defaultValue the value to use if the Character is null 213 * @return the char value of the first letter of the String or the default if null 214 */ 215 public static char toChar(String str, char defaultValue) { 216 if (StringUtils.isEmpty(str)) { 217 return defaultValue; 218 } 219 return str.charAt(0); 220 } 221 222 //----------------------------------------------------------------------- 223 /** 224 * <p>Converts the character to the Integer it represents, throwing an 225 * exception if the character is not numeric.</p> 226 * 227 * <p>This method coverts the char '1' to the int 1 and so on.</p> 228 * 229 * <pre> 230 * CharUtils.toIntValue('3') = 3 231 * CharUtils.toIntValue('A') = IllegalArgumentException 232 * </pre> 233 * 234 * @param ch the character to convert 235 * @return the int value of the character 236 * @throws IllegalArgumentException if the character is not ASCII numeric 237 */ 238 public static int toIntValue(char ch) { 239 if (isAsciiNumeric(ch) == false) { 240 throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'"); 241 } 242 return ch - 48; 243 } 244 245 /** 246 * <p>Converts the character to the Integer it represents, throwing an 247 * exception if the character is not numeric.</p> 248 * 249 * <p>This method coverts the char '1' to the int 1 and so on.</p> 250 * 251 * <pre> 252 * CharUtils.toIntValue('3', -1) = 3 253 * CharUtils.toIntValue('A', -1) = -1 254 * </pre> 255 * 256 * @param ch the character to convert 257 * @param defaultValue the default value to use if the character is not numeric 258 * @return the int value of the character 259 */ 260 public static int toIntValue(char ch, int defaultValue) { 261 if (isAsciiNumeric(ch) == false) { 262 return defaultValue; 263 } 264 return ch - 48; 265 } 266 267 /** 268 * <p>Converts the character to the Integer it represents, throwing an 269 * exception if the character is not numeric.</p> 270 * 271 * <p>This method coverts the char '1' to the int 1 and so on.</p> 272 * 273 * <pre> 274 * CharUtils.toIntValue(null) = IllegalArgumentException 275 * CharUtils.toIntValue('3') = 3 276 * CharUtils.toIntValue('A') = IllegalArgumentException 277 * </pre> 278 * 279 * @param ch the character to convert, not null 280 * @return the int value of the character 281 * @throws IllegalArgumentException if the Character is not ASCII numeric or is null 282 */ 283 public static int toIntValue(Character ch) { 284 if (ch == null) { 285 throw new IllegalArgumentException("The character must not be null"); 286 } 287 return toIntValue(ch.charValue()); 288 } 289 290 /** 291 * <p>Converts the character to the Integer it represents, throwing an 292 * exception if the character is not numeric.</p> 293 * 294 * <p>This method coverts the char '1' to the int 1 and so on.</p> 295 * 296 * <pre> 297 * CharUtils.toIntValue(null, -1) = -1 298 * CharUtils.toIntValue('3', -1) = 3 299 * CharUtils.toIntValue('A', -1) = -1 300 * </pre> 301 * 302 * @param ch the character to convert 303 * @param defaultValue the default value to use if the character is not numeric 304 * @return the int value of the character 305 */ 306 public static int toIntValue(Character ch, int defaultValue) { 307 if (ch == null) { 308 return defaultValue; 309 } 310 return toIntValue(ch.charValue(), defaultValue); 311 } 312 313 //----------------------------------------------------------------------- 314 /** 315 * <p>Converts the character to a String that contains the one character.</p> 316 * 317 * <p>For ASCII 7 bit characters, this uses a cache that will return the 318 * same String object each time.</p> 319 * 320 * <pre> 321 * CharUtils.toString(' ') = " " 322 * CharUtils.toString('A') = "A" 323 * </pre> 324 * 325 * @param ch the character to convert 326 * @return a String containing the one specified character 327 */ 328 public static String toString(char ch) { 329 if (ch < 128) { 330 return CHAR_STRING_ARRAY[ch]; 331 } 332 return new String(new char[] {ch}); 333 } 334 335 /** 336 * <p>Converts the character to a String that contains the one character.</p> 337 * 338 * <p>For ASCII 7 bit characters, this uses a cache that will return the 339 * same String object each time.</p> 340 * 341 * <p>If <code>null</code> is passed in, <code>null</code> will be returned.</p> 342 * 343 * <pre> 344 * CharUtils.toString(null) = null 345 * CharUtils.toString(' ') = " " 346 * CharUtils.toString('A') = "A" 347 * </pre> 348 * 349 * @param ch the character to convert 350 * @return a String containing the one specified character 351 */ 352 public static String toString(Character ch) { 353 if (ch == null) { 354 return null; 355 } 356 return toString(ch.charValue()); 357 } 358 359 //-------------------------------------------------------------------------- 360 /** 361 * <p>Converts the string to the unicode format '\u0020'.</p> 362 * 363 * <p>This format is the Java source code format.</p> 364 * 365 * <pre> 366 * CharUtils.unicodeEscaped(' ') = "\u0020" 367 * CharUtils.unicodeEscaped('A') = "\u0041" 368 * </pre> 369 * 370 * @param ch the character to convert 371 * @return the escaped unicode string 372 */ 373 public static String unicodeEscaped(char ch) { 374 if (ch < 0x10) { 375 return "\\u000" + Integer.toHexString(ch); 376 } else if (ch < 0x100) { 377 return "\\u00" + Integer.toHexString(ch); 378 } else if (ch < 0x1000) { 379 return "\\u0" + Integer.toHexString(ch); 380 } 381 return "\\u" + Integer.toHexString(ch); 382 } 383 384 /** 385 * <p>Converts the string to the unicode format '\u0020'.</p> 386 * 387 * <p>This format is the Java source code format.</p> 388 * 389 * <p>If <code>null</code> is passed in, <code>null</code> will be returned.</p> 390 * 391 * <pre> 392 * CharUtils.unicodeEscaped(null) = null 393 * CharUtils.unicodeEscaped(' ') = "\u0020" 394 * CharUtils.unicodeEscaped('A') = "\u0041" 395 * </pre> 396 * 397 * @param ch the character to convert, may be null 398 * @return the escaped unicode string, null if null input 399 */ 400 public static String unicodeEscaped(Character ch) { 401 if (ch == null) { 402 return null; 403 } 404 return unicodeEscaped(ch.charValue()); 405 } 406 407 //-------------------------------------------------------------------------- 408 /** 409 * <p>Checks whether the character is ASCII 7 bit.</p> 410 * 411 * <pre> 412 * CharUtils.isAscii('a') = true 413 * CharUtils.isAscii('A') = true 414 * CharUtils.isAscii('3') = true 415 * CharUtils.isAscii('-') = true 416 * CharUtils.isAscii('\n') = true 417 * CharUtils.isAscii('©') = false 418 * </pre> 419 * 420 * @param ch the character to check 421 * @return true if less than 128 422 */ 423 public static boolean isAscii(char ch) { 424 return ch < 128; 425 } 426 427 /** 428 * <p>Checks whether the character is ASCII 7 bit printable.</p> 429 * 430 * <pre> 431 * CharUtils.isAsciiPrintable('a') = true 432 * CharUtils.isAsciiPrintable('A') = true 433 * CharUtils.isAsciiPrintable('3') = true 434 * CharUtils.isAsciiPrintable('-') = true 435 * CharUtils.isAsciiPrintable('\n') = false 436 * CharUtils.isAsciiPrintable('©') = false 437 * </pre> 438 * 439 * @param ch the character to check 440 * @return true if between 32 and 126 inclusive 441 */ 442 public static boolean isAsciiPrintable(char ch) { 443 return ch >= 32 && ch < 127; 444 } 445 446 /** 447 * <p>Checks whether the character is ASCII 7 bit control.</p> 448 * 449 * <pre> 450 * CharUtils.isAsciiControl('a') = false 451 * CharUtils.isAsciiControl('A') = false 452 * CharUtils.isAsciiControl('3') = false 453 * CharUtils.isAsciiControl('-') = false 454 * CharUtils.isAsciiControl('\n') = true 455 * CharUtils.isAsciiControl('©') = false 456 * </pre> 457 * 458 * @param ch the character to check 459 * @return true if less than 32 or equals 127 460 */ 461 public static boolean isAsciiControl(char ch) { 462 return ch < 32 || ch == 127; 463 } 464 465 /** 466 * <p>Checks whether the character is ASCII 7 bit alphabetic.</p> 467 * 468 * <pre> 469 * CharUtils.isAsciiAlpha('a') = true 470 * CharUtils.isAsciiAlpha('A') = true 471 * CharUtils.isAsciiAlpha('3') = false 472 * CharUtils.isAsciiAlpha('-') = false 473 * CharUtils.isAsciiAlpha('\n') = false 474 * CharUtils.isAsciiAlpha('©') = false 475 * </pre> 476 * 477 * @param ch the character to check 478 * @return true if between 65 and 90 or 97 and 122 inclusive 479 */ 480 public static boolean isAsciiAlpha(char ch) { 481 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); 482 } 483 484 /** 485 * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p> 486 * 487 * <pre> 488 * CharUtils.isAsciiAlphaUpper('a') = false 489 * CharUtils.isAsciiAlphaUpper('A') = true 490 * CharUtils.isAsciiAlphaUpper('3') = false 491 * CharUtils.isAsciiAlphaUpper('-') = false 492 * CharUtils.isAsciiAlphaUpper('\n') = false 493 * CharUtils.isAsciiAlphaUpper('©') = false 494 * </pre> 495 * 496 * @param ch the character to check 497 * @return true if between 65 and 90 inclusive 498 */ 499 public static boolean isAsciiAlphaUpper(char ch) { 500 return ch >= 'A' && ch <= 'Z'; 501 } 502 503 /** 504 * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p> 505 * 506 * <pre> 507 * CharUtils.isAsciiAlphaLower('a') = true 508 * CharUtils.isAsciiAlphaLower('A') = false 509 * CharUtils.isAsciiAlphaLower('3') = false 510 * CharUtils.isAsciiAlphaLower('-') = false 511 * CharUtils.isAsciiAlphaLower('\n') = false 512 * CharUtils.isAsciiAlphaLower('©') = false 513 * </pre> 514 * 515 * @param ch the character to check 516 * @return true if between 97 and 122 inclusive 517 */ 518 public static boolean isAsciiAlphaLower(char ch) { 519 return ch >= 'a' && ch <= 'z'; 520 } 521 522 /** 523 * <p>Checks whether the character is ASCII 7 bit numeric.</p> 524 * 525 * <pre> 526 * CharUtils.isAsciiNumeric('a') = false 527 * CharUtils.isAsciiNumeric('A') = false 528 * CharUtils.isAsciiNumeric('3') = true 529 * CharUtils.isAsciiNumeric('-') = false 530 * CharUtils.isAsciiNumeric('\n') = false 531 * CharUtils.isAsciiNumeric('©') = false 532 * </pre> 533 * 534 * @param ch the character to check 535 * @return true if between 48 and 57 inclusive 536 */ 537 public static boolean isAsciiNumeric(char ch) { 538 return ch >= '0' && ch <= '9'; 539 } 540 541 /** 542 * <p>Checks whether the character is ASCII 7 bit numeric.</p> 543 * 544 * <pre> 545 * CharUtils.isAsciiAlphanumeric('a') = true 546 * CharUtils.isAsciiAlphanumeric('A') = true 547 * CharUtils.isAsciiAlphanumeric('3') = true 548 * CharUtils.isAsciiAlphanumeric('-') = false 549 * CharUtils.isAsciiAlphanumeric('\n') = false 550 * CharUtils.isAsciiAlphanumeric('©') = false 551 * </pre> 552 * 553 * @param ch the character to check 554 * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive 555 */ 556 public static boolean isAsciiAlphanumeric(char ch) { 557 return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'); 558 } 559 560 }