All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javaemul.internal.StringUtil Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2023 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package javaemul.internal;

/** Utility methods for operating with Strings. */
public final class StringUtil {

  private static final String whitespaceRegexStr =
      "[\\u1680\\u180E\\u2000-\\u2006\\u2008-\\u200A\\u2028\\u2029\\u205F\\u3000\\uFEFF]"
          + "|[\\t-\\r ]"
          + "|[\\x1C-\\x1F]";

  private static NativeRegExp whitespaceRegex;

  public static boolean isWhitespace(String str) {
    if (whitespaceRegex == null) {
      // The regex would just be /\s/, but browsers handle non-breaking spaces inconsistently. Also,
      // the Java definition includes separators.
      whitespaceRegex = new NativeRegExp("^(" + whitespaceRegexStr + ")+$");
    }
    return whitespaceRegex.test(str);
  }

  private static final String spaceRegexStr =
      "[\\u0020\\u00A0\\u1680\\u2000-\\u200A\\u202F\\u2028\\u2029\\u205F\\u3000]";

  private static NativeRegExp spaceRegex;

  public static boolean isSpace(String str) {
    if (spaceRegex == null) {
      spaceRegex = new NativeRegExp("^(" + spaceRegexStr + ")+$");
    }
    return spaceRegex.test(str);
  }

  private static NativeRegExp whitespaceOrSpaceRegex;

  public static boolean isWhitespaceOrSpace(String str) {
    if (whitespaceOrSpaceRegex == null) {
      whitespaceOrSpaceRegex =
          new NativeRegExp("^(" + whitespaceRegexStr + "|" + spaceRegexStr + ")+$");
    }
    return whitespaceOrSpaceRegex.test(str);
  }

  public static String replace(String str, char from, char to, boolean ignoreCase) {
    return nativeReplace(str, escapeForRegExpSearch(from), to, /* replaceAll= */ true, ignoreCase);
  }

  public static String replace(String str, CharSequence from, CharSequence to, boolean ignoreCase) {
    // Implementation note: This uses a regex replacement instead of
    // a string literal replacement because Safari does not
    // follow the spec for "$$" in the replacement string: it
    // will insert a literal "$$". IE and Firefox, meanwhile,
    // treat "$$" as "$".

    return nativeReplace(
        str,
        escapeForRegExpSearch(from),
        escapeForRegExpSearch(to),
        /* replaceAll= */ true,
        ignoreCase);
  }

  /**
   * Regular expressions vary from the standard implementation. The regex parameter is
   * interpreted by JavaScript as a JavaScript regular expression. For consistency, use only the
   * subset of regular expression syntax common to both Java and JavaScript.
   *
   * 

TODO(jat): properly handle Java regex syntax */ public static String replaceAll(String str, String regex, String replace, boolean ignoreCase) { return nativeReplace(str, regex, replace, /* replaceAll= */ true, ignoreCase); } /** * Regular expressions vary from the standard implementation. The regex parameter is * interpreted by JavaScript as a JavaScript regular expression. For consistency, use only the * subset of regular expression syntax common to both Java and JavaScript. * *

TODO(jat): properly handle Java regex syntax */ public static String replaceFirst(String str, String regex, String replace, boolean ignoreCase) { return nativeReplace(str, regex, replace, /* replaceAll= */ false, ignoreCase); } /** Replaces the first instance of the literal match with the literal replacement. */ public static String replaceFirstLiteral(String str, char from, char to, boolean ignoreCase) { return nativeReplace(str, escapeForRegExpSearch(from), to, /* replaceAll= */ false, ignoreCase); } /** Replaces the first instance of the literal match with the literal replacement. */ public static String replaceFirstLiteral( String str, CharSequence from, CharSequence to, boolean ignoreCase) { return nativeReplace( str, escapeForRegExpSearch(from), escapeForRegExpReplacement(to), /* replaceAll= */ false, ignoreCase); } private static String nativeReplace( String str, String regex, String replace, boolean replaceAll, boolean ignoreCase) { String flags = (replaceAll ? "g" : "") + (ignoreCase ? "i" : ""); return str.nativeReplace(new NativeRegExp(regex, flags), translateReplaceString(replace)); } private static String nativeReplace( String str, String regex, char replace, boolean replaceAll, boolean ignoreCase) { String flags = (replaceAll ? "g" : "") + (ignoreCase ? "i" : ""); return str.nativeReplace(new NativeRegExp(regex, flags), replace); } /** * This method converts Java-escaped dollar signs "\$" into JavaScript-escaped dollar signs "$$", * and removes all other lone backslashes, which serve as escapes in Java but are passed through * literally in JavaScript. */ private static String translateReplaceString(String replaceStr) { int pos = 0; while (0 <= (pos = replaceStr.indexOf("\\", pos))) { if (replaceStr.charAt(pos + 1) == '$') { replaceStr = replaceStr.substring(0, pos) + "$" + replaceStr.substring(++pos); } else { replaceStr = replaceStr.substring(0, pos) + replaceStr.substring(++pos); } } return replaceStr; } private static String escapeForRegExpSearch(char c) { // Translate 'from' into unicode escape sequence (\\u and a four-digit hexadecimal number). // Escape sequence replacement is used instead of a string literal replacement // in order to escape regexp special characters (e.g. '.'). String hex = Integer.toHexString(c); return "\\u" + "0000".substring(hex.length()) + hex; } /** Escapes the given CharSerquence such that is can be used in a RegExp search. */ private static String escapeForRegExpSearch(CharSequence str) { return str.toString().replaceAll("([/\\\\\\.\\*\\+\\?\\|\\(\\)\\[\\]\\{\\}$^])", "\\\\$1"); } /** Escapes the given CharSerquence such that is can be used in a RegExp repleacement. */ private static String escapeForRegExpReplacement(CharSequence str) { // Escape $ since it is for match backrefs and \ since it is used to escape $. return str.toString().toString().replaceAll("\\\\", "\\\\\\\\").replaceAll("\\$", "\\\\$"); } private StringUtil() {} }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy