Coverage Report - org.apache.commons.lang3.StringEscapeUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
StringEscapeUtils
94%
32/34
N/A
1,474
StringEscapeUtils$CsvEscaper
90%
10/11
75%
3/4
1,474
StringEscapeUtils$CsvUnescaper
92%
12/13
75%
6/8
1,474
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one or more
 3  
  * contributor license agreements.  See the NOTICE file distributed with
 4  
  * this work for additional information regarding copyright ownership.
 5  
  * The ASF licenses this file to You under the Apache License, Version 2.0
 6  
  * (the "License"); you may not use this file except in compliance with
 7  
  * the License.  You may obtain a copy of the License at
 8  
  * 
 9  
  *      http://www.apache.org/licenses/LICENSE-2.0
 10  
  * 
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 17  
 package org.apache.commons.lang3;
 18  
 
 19  
 import java.io.IOException;
 20  
 import java.io.Writer;
 21  
 
 22  
 import org.apache.commons.lang3.text.translate.AggregateTranslator;
 23  
 import org.apache.commons.lang3.text.translate.CharSequenceTranslator;
 24  
 import org.apache.commons.lang3.text.translate.EntityArrays;
 25  
 import org.apache.commons.lang3.text.translate.JavaUnicodeEscaper;
 26  
 import org.apache.commons.lang3.text.translate.LookupTranslator;
 27  
 import org.apache.commons.lang3.text.translate.NumericEntityEscaper;
 28  
 import org.apache.commons.lang3.text.translate.NumericEntityUnescaper;
 29  
 import org.apache.commons.lang3.text.translate.OctalUnescaper;
 30  
 import org.apache.commons.lang3.text.translate.UnicodeUnescaper;
 31  
 import org.apache.commons.lang3.text.translate.UnicodeUnpairedSurrogateRemover;
 32  
 
 33  
 /**
 34  
  * <p>Escapes and unescapes {@code String}s for
 35  
  * Java, Java Script, HTML and XML.</p>
 36  
  *
 37  
  * <p>#ThreadSafe#</p>
 38  
  * @since 2.0
 39  
  * @version $Id: StringEscapeUtils.java 1583482 2014-03-31 22:54:57Z niallp $
 40  
  */
 41  
 public class StringEscapeUtils {
 42  
 
 43  
     /* ESCAPE TRANSLATORS */
 44  
 
 45  
     /**
 46  
      * Translator object for escaping Java. 
 47  
      * 
 48  
      * While {@link #escapeJava(String)} is the expected method of use, this 
 49  
      * object allows the Java escaping functionality to be used 
 50  
      * as the foundation for a custom translator. 
 51  
      *
 52  
      * @since 3.0
 53  
      */
 54  1
     public static final CharSequenceTranslator ESCAPE_JAVA = 
 55  
           new LookupTranslator(
 56  
             new String[][] { 
 57  
               {"\"", "\\\""},
 58  
               {"\\", "\\\\"},
 59  
           }).with(
 60  
             new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_ESCAPE())
 61  
           ).with(
 62  
             JavaUnicodeEscaper.outsideOf(32, 0x7f) 
 63  
         );
 64  
 
 65  
     /**
 66  
      * Translator object for escaping EcmaScript/JavaScript. 
 67  
      * 
 68  
      * While {@link #escapeEcmaScript(String)} is the expected method of use, this 
 69  
      * object allows the EcmaScript escaping functionality to be used 
 70  
      * as the foundation for a custom translator. 
 71  
      *
 72  
      * @since 3.0
 73  
      */
 74  1
     public static final CharSequenceTranslator ESCAPE_ECMASCRIPT = 
 75  
         new AggregateTranslator(
 76  
             new LookupTranslator(
 77  
                       new String[][] { 
 78  
                             {"'", "\\'"},
 79  
                             {"\"", "\\\""},
 80  
                             {"\\", "\\\\"},
 81  
                             {"/", "\\/"}
 82  
                       }),
 83  
             new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_ESCAPE()),
 84  
             JavaUnicodeEscaper.outsideOf(32, 0x7f) 
 85  
         );
 86  
 
 87  
     /**
 88  
      * Translator object for escaping Json.
 89  
      *
 90  
      * While {@link #escapeJson(String)} is the expected method of use, this
 91  
      * object allows the Json escaping functionality to be used
 92  
      * as the foundation for a custom translator.
 93  
      *
 94  
      * @since 3.2
 95  
      */
 96  1
     public static final CharSequenceTranslator ESCAPE_JSON =
 97  
         new AggregateTranslator(
 98  
             new LookupTranslator(
 99  
                       new String[][] {
 100  
                             {"\"", "\\\""},
 101  
                             {"\\", "\\\\"},
 102  
                             {"/", "\\/"}
 103  
                       }),
 104  
             new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_ESCAPE()),
 105  
             JavaUnicodeEscaper.outsideOf(32, 0x7f)
 106  
         );
 107  
 
 108  
     /**
 109  
      * Translator object for escaping XML.
 110  
      * 
 111  
      * While {@link #escapeXml(String)} is the expected method of use, this 
 112  
      * object allows the XML escaping functionality to be used 
 113  
      * as the foundation for a custom translator. 
 114  
      *
 115  
      * @since 3.0
 116  
      * @deprecated use {@link #ESCAPE_XML10} or {@link #ESCAPE_XML11} instead.
 117  
      */
 118  
     @Deprecated
 119  1
     public static final CharSequenceTranslator ESCAPE_XML = 
 120  
         new AggregateTranslator(
 121  
             new LookupTranslator(EntityArrays.BASIC_ESCAPE()),
 122  
             new LookupTranslator(EntityArrays.APOS_ESCAPE())
 123  
         );
 124  
     
 125  
     /**
 126  
      * Translator object for escaping XML 1.0.
 127  
      * 
 128  
      * While {@link #escapeXml10(String)} is the expected method of use, this
 129  
      * object allows the XML escaping functionality to be used
 130  
      * as the foundation for a custom translator.
 131  
      *
 132  
      * @since 3.3
 133  
      */
 134  1
     public static final CharSequenceTranslator ESCAPE_XML10 =
 135  
         new AggregateTranslator(
 136  
             new LookupTranslator(EntityArrays.BASIC_ESCAPE()),
 137  
             new LookupTranslator(EntityArrays.APOS_ESCAPE()),
 138  
             new LookupTranslator(
 139  
                     new String[][] {
 140  
                             { "\u0000", "" },
 141  
                             { "\u0001", "" },
 142  
                             { "\u0002", "" },
 143  
                             { "\u0003", "" },
 144  
                             { "\u0004", "" },
 145  
                             { "\u0005", "" },
 146  
                             { "\u0006", "" },
 147  
                             { "\u0007", "" },
 148  
                             { "\u0008", "" },
 149  
                             { "\u000b", "" },
 150  
                             { "\u000c", "" },
 151  
                             { "\u000e", "" },
 152  
                             { "\u000f", "" },
 153  
                             { "\u0010", "" },
 154  
                             { "\u0011", "" },
 155  
                             { "\u0012", "" },
 156  
                             { "\u0013", "" },
 157  
                             { "\u0014", "" },
 158  
                             { "\u0015", "" },
 159  
                             { "\u0016", "" },
 160  
                             { "\u0017", "" },
 161  
                             { "\u0018", "" },
 162  
                             { "\u0019", "" },
 163  
                             { "\u001a", "" },
 164  
                             { "\u001b", "" },
 165  
                             { "\u001c", "" },
 166  
                             { "\u001d", "" },
 167  
                             { "\u001e", "" },
 168  
                             { "\u001f", "" },
 169  
                             { "\ufffe", "" },
 170  
                             { "\uffff", "" }
 171  
                     }),
 172  
             NumericEntityEscaper.between(0x7f, 0x84),
 173  
             NumericEntityEscaper.between(0x86, 0x9f),
 174  
             new UnicodeUnpairedSurrogateRemover()
 175  
         );
 176  
     
 177  
     /**
 178  
      * Translator object for escaping XML 1.1.
 179  
      * 
 180  
      * While {@link #escapeXml11(String)} is the expected method of use, this
 181  
      * object allows the XML escaping functionality to be used
 182  
      * as the foundation for a custom translator.
 183  
      *
 184  
      * @since 3.3
 185  
      */
 186  1
     public static final CharSequenceTranslator ESCAPE_XML11 =
 187  
         new AggregateTranslator(
 188  
             new LookupTranslator(EntityArrays.BASIC_ESCAPE()),
 189  
             new LookupTranslator(EntityArrays.APOS_ESCAPE()),
 190  
             new LookupTranslator(
 191  
                     new String[][] {
 192  
                             { "\u0000", "" },
 193  
                             { "\u000b", "&#11;" },
 194  
                             { "\u000c", "&#12;" },
 195  
                             { "\ufffe", "" },
 196  
                             { "\uffff", "" }
 197  
                     }),
 198  
             NumericEntityEscaper.between(0x1, 0x8),
 199  
             NumericEntityEscaper.between(0xe, 0x1f),
 200  
             NumericEntityEscaper.between(0x7f, 0x84),
 201  
             NumericEntityEscaper.between(0x86, 0x9f),
 202  
             new UnicodeUnpairedSurrogateRemover()
 203  
         );
 204  
 
 205  
     /**
 206  
      * Translator object for escaping HTML version 3.0.
 207  
      * 
 208  
      * While {@link #escapeHtml3(String)} is the expected method of use, this 
 209  
      * object allows the HTML escaping functionality to be used 
 210  
      * as the foundation for a custom translator. 
 211  
      *
 212  
      * @since 3.0
 213  
      */
 214  1
     public static final CharSequenceTranslator ESCAPE_HTML3 = 
 215  
         new AggregateTranslator(
 216  
             new LookupTranslator(EntityArrays.BASIC_ESCAPE()),
 217  
             new LookupTranslator(EntityArrays.ISO8859_1_ESCAPE())
 218  
         );
 219  
 
 220  
     /**
 221  
      * Translator object for escaping HTML version 4.0.
 222  
      * 
 223  
      * While {@link #escapeHtml4(String)} is the expected method of use, this 
 224  
      * object allows the HTML escaping functionality to be used 
 225  
      * as the foundation for a custom translator. 
 226  
      *
 227  
      * @since 3.0
 228  
      */
 229  1
     public static final CharSequenceTranslator ESCAPE_HTML4 = 
 230  
         new AggregateTranslator(
 231  
             new LookupTranslator(EntityArrays.BASIC_ESCAPE()),
 232  
             new LookupTranslator(EntityArrays.ISO8859_1_ESCAPE()),
 233  
             new LookupTranslator(EntityArrays.HTML40_EXTENDED_ESCAPE())
 234  
         );
 235  
 
 236  
     /**
 237  
      * Translator object for escaping individual Comma Separated Values. 
 238  
      * 
 239  
      * While {@link #escapeCsv(String)} is the expected method of use, this 
 240  
      * object allows the CSV escaping functionality to be used 
 241  
      * as the foundation for a custom translator. 
 242  
      *
 243  
      * @since 3.0
 244  
      */
 245  1
     public static final CharSequenceTranslator ESCAPE_CSV = new CsvEscaper();
 246  
 
 247  
     // TODO: Create a parent class - 'SinglePassTranslator' ?
 248  
     //       It would handle the index checking + length returning, 
 249  
     //       and could also have an optimization check method.
 250  1
     static class CsvEscaper extends CharSequenceTranslator {
 251  
 
 252  
         private static final char CSV_DELIMITER = ',';
 253  
         private static final char CSV_QUOTE = '"';
 254  1
         private static final String CSV_QUOTE_STR = String.valueOf(CSV_QUOTE);
 255  1
         private static final char[] CSV_SEARCH_CHARS = 
 256  
             new char[] {CSV_DELIMITER, CSV_QUOTE, CharUtils.CR, CharUtils.LF};
 257  
 
 258  
         @Override
 259  
         public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
 260  
 
 261  16
             if(index != 0) {
 262  0
                 throw new IllegalStateException("CsvEscaper should never reach the [1] index");
 263  
             }
 264  
 
 265  16
             if (StringUtils.containsNone(input.toString(), CSV_SEARCH_CHARS)) {
 266  8
                 out.write(input.toString());
 267  
             } else {
 268  8
                 out.write(CSV_QUOTE);
 269  8
                 out.write(StringUtils.replace(input.toString(), CSV_QUOTE_STR, CSV_QUOTE_STR + CSV_QUOTE_STR));
 270  8
                 out.write(CSV_QUOTE);
 271  
             }
 272  16
             return Character.codePointCount(input, 0, input.length());
 273  
         }
 274  
     }
 275  
 
 276  
     /* UNESCAPE TRANSLATORS */
 277  
 
 278  
     /**
 279  
      * Translator object for unescaping escaped Java. 
 280  
      * 
 281  
      * While {@link #unescapeJava(String)} is the expected method of use, this 
 282  
      * object allows the Java unescaping functionality to be used 
 283  
      * as the foundation for a custom translator. 
 284  
      *
 285  
      * @since 3.0
 286  
      */
 287  
     // TODO: throw "illegal character: \92" as an Exception if a \ on the end of the Java (as per the compiler)?
 288  1
     public static final CharSequenceTranslator UNESCAPE_JAVA = 
 289  
         new AggregateTranslator(
 290  
             new OctalUnescaper(),     // .between('\1', '\377'),
 291  
             new UnicodeUnescaper(),
 292  
             new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_UNESCAPE()),
 293  
             new LookupTranslator(
 294  
                       new String[][] { 
 295  
                             {"\\\\", "\\"},
 296  
                             {"\\\"", "\""},
 297  
                             {"\\'", "'"},
 298  
                             {"\\", ""}
 299  
                       })
 300  
         );
 301  
 
 302  
     /**
 303  
      * Translator object for unescaping escaped EcmaScript. 
 304  
      * 
 305  
      * While {@link #unescapeEcmaScript(String)} is the expected method of use, this 
 306  
      * object allows the EcmaScript unescaping functionality to be used 
 307  
      * as the foundation for a custom translator. 
 308  
      *
 309  
      * @since 3.0
 310  
      */
 311  1
     public static final CharSequenceTranslator UNESCAPE_ECMASCRIPT = UNESCAPE_JAVA;
 312  
 
 313  
     /**
 314  
      * Translator object for unescaping escaped Json.
 315  
      *
 316  
      * While {@link #unescapeJson(String)} is the expected method of use, this
 317  
      * object allows the Json unescaping functionality to be used
 318  
      * as the foundation for a custom translator.
 319  
      *
 320  
      * @since 3.2
 321  
      */
 322  1
     public static final CharSequenceTranslator UNESCAPE_JSON = UNESCAPE_JAVA;
 323  
 
 324  
     /**
 325  
      * Translator object for unescaping escaped HTML 3.0. 
 326  
      * 
 327  
      * While {@link #unescapeHtml3(String)} is the expected method of use, this 
 328  
      * object allows the HTML unescaping functionality to be used 
 329  
      * as the foundation for a custom translator. 
 330  
      *
 331  
      * @since 3.0
 332  
      */
 333  1
     public static final CharSequenceTranslator UNESCAPE_HTML3 = 
 334  
         new AggregateTranslator(
 335  
             new LookupTranslator(EntityArrays.BASIC_UNESCAPE()),
 336  
             new LookupTranslator(EntityArrays.ISO8859_1_UNESCAPE()),
 337  
             new NumericEntityUnescaper()
 338  
         );
 339  
 
 340  
     /**
 341  
      * Translator object for unescaping escaped HTML 4.0. 
 342  
      * 
 343  
      * While {@link #unescapeHtml4(String)} is the expected method of use, this 
 344  
      * object allows the HTML unescaping functionality to be used 
 345  
      * as the foundation for a custom translator. 
 346  
      *
 347  
      * @since 3.0
 348  
      */
 349  1
     public static final CharSequenceTranslator UNESCAPE_HTML4 = 
 350  
         new AggregateTranslator(
 351  
             new LookupTranslator(EntityArrays.BASIC_UNESCAPE()),
 352  
             new LookupTranslator(EntityArrays.ISO8859_1_UNESCAPE()),
 353  
             new LookupTranslator(EntityArrays.HTML40_EXTENDED_UNESCAPE()),
 354  
             new NumericEntityUnescaper()
 355  
         );
 356  
 
 357  
     /**
 358  
      * Translator object for unescaping escaped XML.
 359  
      * 
 360  
      * While {@link #unescapeXml(String)} is the expected method of use, this 
 361  
      * object allows the XML unescaping functionality to be used 
 362  
      * as the foundation for a custom translator. 
 363  
      *
 364  
      * @since 3.0
 365  
      */
 366  1
     public static final CharSequenceTranslator UNESCAPE_XML = 
 367  
         new AggregateTranslator(
 368  
             new LookupTranslator(EntityArrays.BASIC_UNESCAPE()),
 369  
             new LookupTranslator(EntityArrays.APOS_UNESCAPE()),
 370  
             new NumericEntityUnescaper()
 371  
         );
 372  
 
 373  
     /**
 374  
      * Translator object for unescaping escaped Comma Separated Value entries.
 375  
      * 
 376  
      * While {@link #unescapeCsv(String)} is the expected method of use, this 
 377  
      * object allows the CSV unescaping functionality to be used 
 378  
      * as the foundation for a custom translator. 
 379  
      *
 380  
      * @since 3.0
 381  
      */
 382  1
     public static final CharSequenceTranslator UNESCAPE_CSV = new CsvUnescaper();
 383  
 
 384  1
     static class CsvUnescaper extends CharSequenceTranslator {
 385  
 
 386  
         private static final char CSV_DELIMITER = ',';
 387  
         private static final char CSV_QUOTE = '"';
 388  1
         private static final String CSV_QUOTE_STR = String.valueOf(CSV_QUOTE);
 389  1
         private static final char[] CSV_SEARCH_CHARS = 
 390  
             new char[] {CSV_DELIMITER, CSV_QUOTE, CharUtils.CR, CharUtils.LF};
 391  
 
 392  
         @Override
 393  
         public int translate(final CharSequence input, final int index, final Writer out) throws IOException {
 394  
 
 395  18
             if(index != 0) {
 396  0
                 throw new IllegalStateException("CsvUnescaper should never reach the [1] index");
 397  
             }
 398  
 
 399  18
             if ( input.charAt(0) != CSV_QUOTE || input.charAt(input.length() - 1) != CSV_QUOTE ) {
 400  8
                 out.write(input.toString());
 401  8
                 return Character.codePointCount(input, 0, input.length());
 402  
             }
 403  
 
 404  
             // strip quotes
 405  10
             final String quoteless = input.subSequence(1, input.length() - 1).toString();
 406  
 
 407  10
             if ( StringUtils.containsAny(quoteless, CSV_SEARCH_CHARS) ) {
 408  
                 // deal with escaped quotes; ie) ""
 409  8
                 out.write(StringUtils.replace(quoteless, CSV_QUOTE_STR + CSV_QUOTE_STR, CSV_QUOTE_STR));
 410  
             } else {
 411  2
                 out.write(input.toString());
 412  
             }
 413  10
             return Character.codePointCount(input, 0, input.length());
 414  
         }
 415  
     }
 416  
 
 417  
     /* Helper functions */
 418  
 
 419  
     /**
 420  
      * <p>{@code StringEscapeUtils} instances should NOT be constructed in
 421  
      * standard programming.</p>
 422  
      *
 423  
      * <p>Instead, the class should be used as:</p>
 424  
      * <pre>StringEscapeUtils.escapeJava("foo");</pre>
 425  
      *
 426  
      * <p>This constructor is public to permit tools that require a JavaBean
 427  
      * instance to operate.</p>
 428  
      */
 429  
     public StringEscapeUtils() {
 430  1
       super();
 431  1
     }
 432  
 
 433  
     // Java and JavaScript
 434  
     //--------------------------------------------------------------------------
 435  
     /**
 436  
      * <p>Escapes the characters in a {@code String} using Java String rules.</p>
 437  
      *
 438  
      * <p>Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.) </p>
 439  
      *
 440  
      * <p>So a tab becomes the characters {@code '\\'} and
 441  
      * {@code 't'}.</p>
 442  
      *
 443  
      * <p>The only difference between Java strings and JavaScript strings
 444  
      * is that in JavaScript, a single quote and forward-slash (/) are escaped.</p>
 445  
      *
 446  
      * <p>Example:</p>
 447  
      * <pre>
 448  
      * input string: He didn't say, "Stop!"
 449  
      * output string: He didn't say, \"Stop!\"
 450  
      * </pre>
 451  
      *
 452  
      * @param input  String to escape values in, may be null
 453  
      * @return String with escaped values, {@code null} if null string input
 454  
      */
 455  
     public static final String escapeJava(final String input) {
 456  36
         return ESCAPE_JAVA.translate(input);
 457  
     }
 458  
 
 459  
     /**
 460  
      * <p>Escapes the characters in a {@code String} using EcmaScript String rules.</p>
 461  
      * <p>Escapes any values it finds into their EcmaScript String form.
 462  
      * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.) </p>
 463  
      *
 464  
      * <p>So a tab becomes the characters {@code '\\'} and
 465  
      * {@code 't'}.</p>
 466  
      *
 467  
      * <p>The only difference between Java strings and EcmaScript strings
 468  
      * is that in EcmaScript, a single quote and forward-slash (/) are escaped.</p>
 469  
      *
 470  
      * <p>Note that EcmaScript is best known by the JavaScript and ActionScript dialects. </p>
 471  
      *
 472  
      * <p>Example:</p>
 473  
      * <pre>
 474  
      * input string: He didn't say, "Stop!"
 475  
      * output string: He didn\'t say, \"Stop!\"
 476  
      * </pre>
 477  
      *
 478  
      * @param input  String to escape values in, may be null
 479  
      * @return String with escaped values, {@code null} if null string input
 480  
      *
 481  
      * @since 3.0
 482  
      */
 483  
     public static final String escapeEcmaScript(final String input) {
 484  5
         return ESCAPE_ECMASCRIPT.translate(input);
 485  
     }
 486  
 
 487  
     /**
 488  
      * <p>Escapes the characters in a {@code String} using Json String rules.</p>
 489  
      * <p>Escapes any values it finds into their Json String form.
 490  
      * Deals correctly with quotes and control-chars (tab, backslash, cr, ff, etc.) </p>
 491  
      *
 492  
      * <p>So a tab becomes the characters {@code '\\'} and
 493  
      * {@code 't'}.</p>
 494  
      *
 495  
      * <p>The only difference between Java strings and Json strings
 496  
      * is that in Json, forward-slash (/) is escaped.</p>
 497  
      *
 498  
      * <p>See http://www.ietf.org/rfc/rfc4627.txt for further details. </p>
 499  
      *
 500  
      * <p>Example:</p>
 501  
      * <pre>
 502  
      * input string: He didn't say, "Stop!"
 503  
      * output string: He didn't say, \"Stop!\"
 504  
      * </pre>
 505  
      *
 506  
      * @param input  String to escape values in, may be null
 507  
      * @return String with escaped values, {@code null} if null string input
 508  
      *
 509  
      * @since 3.2
 510  
      */
 511  
     public static final String escapeJson(final String input) {
 512  3
         return ESCAPE_JSON.translate(input);
 513  
     }
 514  
 
 515  
     /**
 516  
      * <p>Unescapes any Java literals found in the {@code String}.
 517  
      * For example, it will turn a sequence of {@code '\'} and
 518  
      * {@code 'n'} into a newline character, unless the {@code '\'}
 519  
      * is preceded by another {@code '\'}.</p>
 520  
      * 
 521  
      * @param input  the {@code String} to unescape, may be null
 522  
      * @return a new unescaped {@code String}, {@code null} if null string input
 523  
      */
 524  
     public static final String unescapeJava(final String input) {
 525  12
         return UNESCAPE_JAVA.translate(input);
 526  
     }
 527  
 
 528  
     /**
 529  
      * <p>Unescapes any EcmaScript literals found in the {@code String}.</p>
 530  
      *
 531  
      * <p>For example, it will turn a sequence of {@code '\'} and {@code 'n'}
 532  
      * into a newline character, unless the {@code '\'} is preceded by another
 533  
      * {@code '\'}.</p>
 534  
      *
 535  
      * @see #unescapeJava(String)
 536  
      * @param input  the {@code String} to unescape, may be null
 537  
      * @return A new unescaped {@code String}, {@code null} if null string input
 538  
      *
 539  
      * @since 3.0
 540  
      */
 541  
     public static final String unescapeEcmaScript(final String input) {
 542  0
         return UNESCAPE_ECMASCRIPT.translate(input);
 543  
     }
 544  
 
 545  
     /**
 546  
      * <p>Unescapes any Json literals found in the {@code String}.</p>
 547  
      *
 548  
      * <p>For example, it will turn a sequence of {@code '\'} and {@code 'n'}
 549  
      * into a newline character, unless the {@code '\'} is preceded by another
 550  
      * {@code '\'}.</p>
 551  
      *
 552  
      * @see #unescapeJava(String)
 553  
      * @param input  the {@code String} to unescape, may be null
 554  
      * @return A new unescaped {@code String}, {@code null} if null string input
 555  
      *
 556  
      * @since 3.2
 557  
      */
 558  
     public static final String unescapeJson(final String input) {
 559  0
         return UNESCAPE_JSON.translate(input);
 560  
     }
 561  
 
 562  
     // HTML and XML
 563  
     //--------------------------------------------------------------------------
 564  
     /**
 565  
      * <p>Escapes the characters in a {@code String} using HTML entities.</p>
 566  
      *
 567  
      * <p>
 568  
      * For example:
 569  
      * </p> 
 570  
      * <p><code>"bread" &amp; "butter"</code></p>
 571  
      * becomes:
 572  
      * <p>
 573  
      * <code>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</code>.
 574  
      * </p>
 575  
      *
 576  
      * <p>Supports all known HTML 4.0 entities, including funky accents.
 577  
      * Note that the commonly used apostrophe escape character (&amp;apos;)
 578  
      * is not a legal entity and so is not supported). </p>
 579  
      *
 580  
      * @param input  the {@code String} to escape, may be null
 581  
      * @return a new escaped {@code String}, {@code null} if null string input
 582  
      * 
 583  
      * @see <a href="http://hotwired.lycos.com/webmonkey/reference/special_characters/">ISO Entities</a>
 584  
      * @see <a href="http://www.w3.org/TR/REC-html32#latin1">HTML 3.2 Character Entities for ISO Latin-1</a>
 585  
      * @see <a href="http://www.w3.org/TR/REC-html40/sgml/entities.html">HTML 4.0 Character entity references</a>
 586  
      * @see <a href="http://www.w3.org/TR/html401/charset.html#h-5.3">HTML 4.01 Character References</a>
 587  
      * @see <a href="http://www.w3.org/TR/html401/charset.html#code-position">HTML 4.01 Code positions</a>
 588  
      * 
 589  
      * @since 3.0
 590  
      */
 591  
     public static final String escapeHtml4(final String input) {
 592  211
         return ESCAPE_HTML4.translate(input);
 593  
     }
 594  
 
 595  
     /**
 596  
      * <p>Escapes the characters in a {@code String} using HTML entities.</p>
 597  
      * <p>Supports only the HTML 3.0 entities. </p>
 598  
      *
 599  
      * @param input  the {@code String} to escape, may be null
 600  
      * @return a new escaped {@code String}, {@code null} if null string input
 601  
      * 
 602  
      * @since 3.0
 603  
      */
 604  
     public static final String escapeHtml3(final String input) {
 605  1
         return ESCAPE_HTML3.translate(input);
 606  
     }
 607  
 
 608  
     //-----------------------------------------------------------------------
 609  
     /**
 610  
      * <p>Unescapes a string containing entity escapes to a string
 611  
      * containing the actual Unicode characters corresponding to the
 612  
      * escapes. Supports HTML 4.0 entities.</p>
 613  
      *
 614  
      * <p>For example, the string "&amp;lt;Fran&amp;ccedil;ais&amp;gt;"
 615  
      * will become "&lt;Fran&ccedil;ais&gt;"</p>
 616  
      *
 617  
      * <p>If an entity is unrecognized, it is left alone, and inserted
 618  
      * verbatim into the result string. e.g. "&amp;gt;&amp;zzzz;x" will
 619  
      * become "&gt;&amp;zzzz;x".</p>
 620  
      *
 621  
      * @param input  the {@code String} to unescape, may be null
 622  
      * @return a new unescaped {@code String}, {@code null} if null string input
 623  
      * 
 624  
      * @since 3.0
 625  
      */
 626  
     public static final String unescapeHtml4(final String input) {
 627  65561
         return UNESCAPE_HTML4.translate(input);
 628  
     }
 629  
 
 630  
     /**
 631  
      * <p>Unescapes a string containing entity escapes to a string
 632  
      * containing the actual Unicode characters corresponding to the
 633  
      * escapes. Supports only HTML 3.0 entities.</p>
 634  
      *
 635  
      * @param input  the {@code String} to unescape, may be null
 636  
      * @return a new unescaped {@code String}, {@code null} if null string input
 637  
      * 
 638  
      * @since 3.0
 639  
      */
 640  
     public static final String unescapeHtml3(final String input) {
 641  1
         return UNESCAPE_HTML3.translate(input);
 642  
     }
 643  
 
 644  
     //-----------------------------------------------------------------------
 645  
     /**
 646  
      * <p>Escapes the characters in a {@code String} using XML entities.</p>
 647  
      *
 648  
      * <p>For example: <tt>"bread" &amp; "butter"</tt> =&gt;
 649  
      * <tt>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</tt>.
 650  
      * </p>
 651  
      *
 652  
      * <p>Supports only the five basic XML entities (gt, lt, quot, amp, apos).
 653  
      * Does not support DTDs or external entities.</p>
 654  
      *
 655  
      * <p>Note that Unicode characters greater than 0x7f are as of 3.0, no longer 
 656  
      *    escaped. If you still wish this functionality, you can achieve it 
 657  
      *    via the following: 
 658  
      * {@code StringEscapeUtils.ESCAPE_XML.with( NumericEntityEscaper.between(0x7f, Integer.MAX_VALUE) );}</p>
 659  
      *
 660  
      * @param input  the {@code String} to escape, may be null
 661  
      * @return a new escaped {@code String}, {@code null} if null string input
 662  
      * @see #unescapeXml(java.lang.String)
 663  
      * @deprecated use {@link #escapeXml10(java.lang.String)} or {@link #escapeXml11(java.lang.String)} instead.
 664  
      */
 665  
     @Deprecated
 666  
     public static final String escapeXml(final String input) {
 667  7
         return ESCAPE_XML.translate(input);
 668  
     }
 669  
 
 670  
     /**
 671  
      * <p>Escapes the characters in a {@code String} using XML entities.</p>
 672  
      *
 673  
      * <p>For example: <tt>"bread" &amp; "butter"</tt> =&gt;
 674  
      * <tt>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</tt>.
 675  
      * </p>
 676  
      *
 677  
      * <p>Note that XML 1.0 is a text-only format: it cannot represent control
 678  
      * characters or unpaired Unicode surrogate codepoints, even after escaping.
 679  
      * {@code escapeXml10} will remove characters that do not fit in the
 680  
      * following ranges:</p>
 681  
      * 
 682  
      * <p>{@code #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]}</p>
 683  
      * 
 684  
      * <p>Though not strictly necessary, {@code escapeXml10} will escape
 685  
      * characters in the following ranges:</p>
 686  
      * 
 687  
      * <p>{@code [#x7F-#x84] | [#x86-#x9F]}</p>
 688  
      * 
 689  
      * <p>The returned string can be inserted into a valid XML 1.0 or XML 1.1
 690  
      * document. If you want to allow more non-text characters in an XML 1.1
 691  
      * document, use {@link #escapeXml11(String)}.</p>
 692  
      *
 693  
      * @param input  the {@code String} to escape, may be null
 694  
      * @return a new escaped {@code String}, {@code null} if null string input
 695  
      * @see #unescapeXml(java.lang.String)
 696  
      * @since 3.3
 697  
      */
 698  
     public static String escapeXml10(final String input) {
 699  6
         return ESCAPE_XML10.translate(input);
 700  
     }
 701  
     
 702  
     /**
 703  
      * <p>Escapes the characters in a {@code String} using XML entities.</p>
 704  
      *
 705  
      * <p>For example: <tt>"bread" &amp; "butter"</tt> =&gt;
 706  
      * <tt>&amp;quot;bread&amp;quot; &amp;amp; &amp;quot;butter&amp;quot;</tt>.
 707  
      * </p>
 708  
      *
 709  
      * <p>XML 1.1 can represent certain control characters, but it cannot represent
 710  
      * the null byte or unpaired Unicode surrogate codepoints, even after escaping.
 711  
      * {@code escapeXml11} will remove characters that do not fit in the following
 712  
      * ranges:</p>
 713  
      * 
 714  
      * <p>{@code [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]}</p>
 715  
      * 
 716  
      * <p>{@code escapeXml11} will escape characters in the following ranges:</p>
 717  
      * 
 718  
      * <p>{@code [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]}</p>
 719  
      * 
 720  
      * <p>The returned string can be inserted into a valid XML 1.1 document. Do not
 721  
      * use it for XML 1.0 documents.</p>
 722  
      *
 723  
      * @param input  the {@code String} to escape, may be null
 724  
      * @return a new escaped {@code String}, {@code null} if null string input
 725  
      * @see #unescapeXml(java.lang.String)
 726  
      * @since 3.3
 727  
      */
 728  
     public static String escapeXml11(final String input) {
 729  7
         return ESCAPE_XML11.translate(input);
 730  
     }
 731  
 
 732  
     //-----------------------------------------------------------------------
 733  
     /**
 734  
      * <p>Unescapes a string containing XML entity escapes to a string
 735  
      * containing the actual Unicode characters corresponding to the
 736  
      * escapes.</p>
 737  
      *
 738  
      * <p>Supports only the five basic XML entities (gt, lt, quot, amp, apos).
 739  
      * Does not support DTDs or external entities.</p>
 740  
      *
 741  
      * <p>Note that numerical \\u Unicode codes are unescaped to their respective 
 742  
      *    Unicode characters. This may change in future releases. </p>
 743  
      *
 744  
      * @param input  the {@code String} to unescape, may be null
 745  
      * @return a new unescaped {@code String}, {@code null} if null string input
 746  
      * @see #escapeXml(String)
 747  
      * @see #escapeXml10(String)
 748  
      * @see #escapeXml11(String)
 749  
      */
 750  
     public static final String unescapeXml(final String input) {
 751  11
         return UNESCAPE_XML.translate(input);
 752  
     }
 753  
 
 754  
     //-----------------------------------------------------------------------
 755  
 
 756  
     /**
 757  
      * <p>Returns a {@code String} value for a CSV column enclosed in double quotes,
 758  
      * if required.</p>
 759  
      *
 760  
      * <p>If the value contains a comma, newline or double quote, then the
 761  
      *    String value is returned enclosed in double quotes.</p>
 762  
      *
 763  
      * <p>Any double quote characters in the value are escaped with another double quote.</p>
 764  
      *
 765  
      * <p>If the value does not contain a comma, newline or double quote, then the
 766  
      *    String value is returned unchanged.</p>
 767  
      *
 768  
      * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikipedia</a> and
 769  
      * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
 770  
      *
 771  
      * @param input the input CSV column String, may be null
 772  
      * @return the input String, enclosed in double quotes if the value contains a comma,
 773  
      * newline or double quote, {@code null} if null string input
 774  
      * @since 2.4
 775  
      */
 776  
     public static final String escapeCsv(final String input) {
 777  12
         return ESCAPE_CSV.translate(input);
 778  
     }
 779  
 
 780  
     /**
 781  
      * <p>Returns a {@code String} value for an unescaped CSV column. </p>
 782  
      *
 783  
      * <p>If the value is enclosed in double quotes, and contains a comma, newline 
 784  
      *    or double quote, then quotes are removed. 
 785  
      * </p>
 786  
      *
 787  
      * <p>Any double quote escaped characters (a pair of double quotes) are unescaped 
 788  
      *    to just one double quote. </p>
 789  
      *
 790  
      * <p>If the value is not enclosed in double quotes, or is and does not contain a 
 791  
      *    comma, newline or double quote, then the String value is returned unchanged.</p>
 792  
      *
 793  
      * see <a href="http://en.wikipedia.org/wiki/Comma-separated_values">Wikipedia</a> and
 794  
      * <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
 795  
      *
 796  
      * @param input the input CSV column String, may be null
 797  
      * @return the input String, with enclosing double quotes removed and embedded double 
 798  
      * quotes unescaped, {@code null} if null string input
 799  
      * @since 2.4
 800  
      */
 801  
     public static final String unescapeCsv(final String input) {
 802  13
         return UNESCAPE_CSV.translate(input);
 803  
     }
 804  
 
 805  
 }