private String strEscape(
      String s,
      String doublequoteEscape,
      String singlequoteEscape,
      String backtickEscape,
      String backslashEscape,
      String dollarEscape,
      boolean useSlashV,
      boolean isRegexp) {
    StringBuilder sb = new StringBuilder(s.length() + 2);
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      switch (c) {
        case '\0': sb.append("\\x00"); break;
        case '\u000B':
          if (useSlashV) {
            sb.append("\\v");
          } else {
            sb.append("\\x0B");
          }
          break;
        // From the SingleEscapeCharacter grammar production.
        case '\b': sb.append("\\b"); break;
        case '\f': sb.append("\\f"); break;
        case '\n': sb.append("\\n"); break;
        case '\r': sb.append("\\r"); break;
        case '\t': sb.append("\\t"); break;
        case '\\': sb.append(backslashEscape); break;
        case '\"': sb.append(doublequoteEscape); break;
        case '\'': sb.append(singlequoteEscape); break;
        case '$': sb.append(dollarEscape); break;
        case '`': sb.append(backtickEscape); break;

        case '=':
          // '=' is a syntactically significant regexp character.
          if (trustedStrings || isRegexp) {
            sb.append(c);
          } else {
            sb.append("\\x3d");
          }
          break;

        case '&':
          if (trustedStrings || isRegexp) {
            sb.append(c);
          } else {
            sb.append("\\x26");
          }
          break;

        case '>':
          if (!trustedStrings && !isRegexp) {
            sb.append(GT_ESCAPED);
            break;
          }

          // Break --> into --\> or ]]> into ]]\>
          //
          // This is just to prevent developers from shooting themselves in the
          // foot, and does not provide the level of security that you get
          // with trustedString == false.
          if (i >= 2
              && ((s.charAt(i - 1) == '-' && s.charAt(i - 2) == '-')
                  || (s.charAt(i - 1) == ']' && s.charAt(i - 2) == ']'))) {
            sb.append(GT_ESCAPED);
          } else {
            sb.append(c);
          }
          break;
        case '<':
          if (!trustedStrings && !isRegexp) {
            sb.append(LT_ESCAPED);
            break;
          }

          // Break </script into <\/script
          // As above, this is just to prevent developers from doing this
          // accidentally.
          final String endScript = "/script";

          // Break <!-- into <\!--
          final String startComment = "!--";

          if (s.regionMatches(true, i + 1, endScript, 0, endScript.length())) {
            sb.append(LT_ESCAPED);
          } else if (s.regionMatches(false, i + 1, startComment, 0, startComment.length())) {
            sb.append(LT_ESCAPED);
          } else {
            sb.append(c);
          }
          break;

        default:
          if (isRegexp
              || !outputFeatureSet.contains(Feature.UNESCAPED_UNICODE_LINE_OR_PARAGRAPH_SEP)) {
            // In 2019 these characters (line and paragraph separators) are valid in strings but
            // not regular expressions.
            // https://github.com/tc39/proposal-json-superset
            if (c == '\u2028') {
              sb.append("\\u2028");
              break;
            }
            if (c == '\u2029') {
              sb.append("\\u2029");
              break;
            }
          }

          if ((outputCharsetEncoder != null && outputCharsetEncoder.canEncode(c))
              || (c > 0x1f && c < 0x7f)) {
            // If we're given an outputCharsetEncoder, then check if the character can be
            // represented in this character set. If no charsetEncoder provided - pass straight
            // Latin characters through, and escape the rest. Doing the explicit character check is
            // measurably faster than using the CharsetEncoder.
            sb.append(c);
          } else {
            // Other characters can be misinterpreted by some JS parsers,
            // or perhaps mangled by proxies along the way,
            // so we play it safe and Unicode escape them.
            Util.appendHexJavaScriptRepresentation(sb, c);
          }
      }
    }
    return sb.toString();
  }
private String strEscape ( String s , String doublequoteEscape , String singlequoteEscape , String backtickEscape , String backslashEscape , String dollarEscape , boolean useSlashV , boolean isRegexp ) { StringBuilder sb = new StringBuilder ( s . length ( ) + 2 ) ; for ( int i = 0 ; i < s . length ( ) ; i ++ ) { char c = s . charAt ( i ) ; switch ( c ) { case '\0' : sb . append ( "\\x00" ) ; break ; case '' : if ( useSlashV ) { sb . append ( "\\v" ) ; } else { sb . append ( "\\x0B" ) ; } break ; case '\b' : sb . append ( "\\b" ) ; break ; case '\f' : sb . append ( "\\f" ) ; break ; case '\n' : sb . append ( "\\n" ) ; break ; case '\r' : sb . append ( "\\r" ) ; break ; case '\t' : sb . append ( "\\t" ) ; break ; case '\\' : sb . append ( backslashEscape ) ; break ; case '\"' : sb . append ( doublequoteEscape ) ; break ; case '\'' : sb . append ( singlequoteEscape ) ; break ; case '$' : sb . append ( dollarEscape ) ; break ; case '`' : sb . append ( backtickEscape ) ; break ; case '=' : if ( trustedStrings || isRegexp ) { sb . append ( c ) ; } else { sb . append ( "\\x3d" ) ; } break ; case '&' : if ( trustedStrings || isRegexp ) { sb . append ( c ) ; } else { sb . append ( "\\x26" ) ; } break ; case '>' : if ( ! trustedStrings && ! isRegexp ) { sb . append ( GT_ESCAPED ) ; break ; } if ( i >= 2 && ( ( s . charAt ( i - 1 ) == '-' && s . charAt ( i - 2 ) == '-' ) || ( s . charAt ( i - 1 ) == ']' && s . charAt ( i - 2 ) == ']' ) ) ) { sb . append ( GT_ESCAPED ) ; } else { sb . append ( c ) ; } break ; case '<' : if ( ! trustedStrings && ! isRegexp ) { sb . append ( LT_ESCAPED ) ; break ; } final String endScript = "/script" ; final String startComment = "!--" ; if ( s . regionMatches ( true , i + 1 , endScript , 0 , endScript . length ( ) ) ) { sb . append ( LT_ESCAPED ) ; } else if ( s . regionMatches ( false , i + 1 , startComment , 0 , startComment . length ( ) ) ) { sb . append ( LT_ESCAPED ) ; } else { sb . append ( c ) ; } break ; default : if ( isRegexp || ! outputFeatureSet . contains ( Feature . UNESCAPED_UNICODE_LINE_OR_PARAGRAPH_SEP ) ) { if ( c == ' ' ) { sb . append ( "\\u2028" ) ; break ; } if ( c == ' ' ) { sb . append ( "\\u2029" ) ; break ; } } if ( ( outputCharsetEncoder != null && outputCharsetEncoder . canEncode ( c ) ) || ( c > 0x1f && c < 0x7f ) ) { sb . append ( c ) ; } else { Util . appendHexJavaScriptRepresentation ( sb , c ) ; } } } return sb . toString ( ) ; }
Helper to escape JavaScript string as well as regular expression