cauchoregexpmodule.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,953 行 · 第 1/4 页

JAVA
1,953
字号
          Callback fun,          Value subject,          @Optional("-1") long limit,          @Optional @Reference Value count)  {    try {      if (subject instanceof ArrayValue) {        ArrayValue result = new ArrayValueImpl();        for (Value value : ((ArrayValue) subject).values()) {          result.put(pregReplaceCallback(env,              pattern.toStringValue(),              fun,              value.toStringValue(),              limit,              count));        }        return result;      } else if (subject.isset()) {        return pregReplaceCallback(env,            pattern.toStringValue(),            fun,            subject.toStringValue(),            limit,            count);      } else {        return env.getEmptyString();      }    }    catch (IllegalRegexpException e) {       log.log(Level.FINE, e.getMessage(), e);      env.warning(e);            return BooleanValue.FALSE;    }  }  /**   * Replaces values using regexps   */  private static Value pregReplaceCallback(Env env,          Value patternValue,          Callback fun,          StringValue subject,          @Optional("-1") long limit,          @Optional @Reference Value countV)    throws IllegalRegexpException  {    if (limit < 0)      limit = LONG_MAX;    if (patternValue.isArray()) {      ArrayValue patternArray = (ArrayValue) patternValue;      for (Value value : patternArray.values()) {        subject = pregReplaceCallbackImpl(env,                value.toStringValue(),                fun,                subject,                limit,                countV);      }      return subject;    } else if (subject.isset()) {      return pregReplaceCallbackImpl(env,              patternValue.toStringValue(),              fun,              subject,              limit,              countV);    } else {      return env.getEmptyString();    }  }  /**   * Returns array of substrings or   * of arrays ([0] => substring [1] => offset) if   * PREG_SPLIT_OFFSET_CAPTURE is set   *   * @param env the calling environment   */  public static Value preg_split(Env env,				 StringValue patternString,				 StringValue string,				 @Optional("-1") long limit,				 @Optional int flags)  {    try {          if (limit <= 0)	limit = LONG_MAX;      StringValue empty = patternString.getEmptyString();          Regexp regexp = getRegexp(env, patternString);      RegexpState regexpState = new RegexpState(env, regexp, string);      ArrayValue result = new ArrayValueImpl();      int head = 0;      long count = 0;      boolean allowEmpty = (flags & PREG_SPLIT_NO_EMPTY) == 0;      boolean isCaptureOffset = (flags & PREG_SPLIT_OFFSET_CAPTURE) != 0;       boolean isCaptureDelim = (flags & PREG_SPLIT_DELIM_CAPTURE) != 0;      GroupNeighborMap neighborMap	= new GroupNeighborMap(regexp.getPattern(), regexpState.groupCount());          while (regexpState.find()) {	int startPosition = head;	StringValue unmatched;	// Get non-matching sequence	if (count == limit - 1) {	  unmatched = string.substring(head);	  head = string.length();	}	else {	  unmatched = string.substring(head, regexpState.start());	  head = regexpState.end();	}	// Append non-matching sequence	if (unmatched.length() != 0 || allowEmpty) {	  if (isCaptureOffset) {	    ArrayValue part = new ArrayValueImpl();	    part.put(unmatched);	    part.put(LongValue.create(startPosition));	    result.put(part);	  }	  else {	    result.put(unmatched);	  }	  count++;	}	if (count == limit)	  break;	// Append parameterized delimiters	if (isCaptureDelim) {	  for (int i = 1; i < regexpState.groupCount(); i++) {	    int start = regexpState.start(i);	    int end = regexpState.end(i);	    // Skip empty groups	    if (! regexpState.isMatchedGroup(i)) {	      continue;	    }	    // Append empty OR neighboring groups that were skipped	    // php/152r	    if (allowEmpty) {	      int group = i;	      while (neighborMap.hasNeighbor(group)) {		group = neighborMap.getNeighbor(group);		if (regexpState.isMatchedGroup(group))		  break;		if (isCaptureOffset) {		  ArrayValue part = new ArrayValueImpl();		  part.put(empty);		  part.put(LongValue.create(startPosition));		  result.put(part);		}		else		  result.put(empty);	      }	    }	    if (end - start <= 0 && ! allowEmpty) {	      continue;	    }	    StringValue groupValue = regexpState.group(env, i);	    if (isCaptureOffset) {	      ArrayValue part = new ArrayValueImpl();	      part.put(groupValue);	      part.put(LongValue.create(startPosition));	      result.put(part);	    }	    else {	      result.put(groupValue);	    }	  }	}      }      // Append non-matching sequence at the end      if (count < limit && (head < string.length() || allowEmpty)) {	if (isCaptureOffset) {	  ArrayValue part = new ArrayValueImpl();	  part.put(string.substring(head));	  part.put(LongValue.create(head));	  result.put(part);	}	else {	  result.put(string.substring(head));	}      }      return result;    }    catch (IllegalRegexpException e) {      log.log(Level.FINE, e.getMessage(), e);      env.warning(e);            return BooleanValue.FALSE;    }  }  /**   * Makes a regexp for a case-insensitive match.   */  public static StringValue sql_regcase(StringValue string)  {    StringValue sb = string.createStringBuilder();    int len = string.length();    for (int i = 0; i < len; i++) {      char ch = string.charAt(i);      if (Character.isLowerCase(ch)) {        sb.append('[');        sb.append(Character.toUpperCase(ch));        sb.append(ch);        sb.append(']');      }      else if (Character.isUpperCase(ch)) {        sb.append('[');        sb.append(ch);        sb.append(Character.toLowerCase(ch));        sb.append(']');      }      else        sb.append(ch);    }    return sb;  }  /**   * Returns an array of strings produces from splitting the passed string   * around the provided pattern.  The pattern is case sensitive.   *   * @param patternString the pattern   * @param string the string to split   * @param limit if specified, the maximum number of elements in the array   * @return an array of strings split around the pattern string   */  public static Value split(Env env,			    StringValue patternString,			    StringValue string,			    @Optional("-1") long limit)  {    return splitImpl(env, patternString, string, limit, false);  }  /**   * Returns an array of strings produces from splitting the passed string   * around the provided pattern.  The pattern is case insensitive.   *   * @param patternString the pattern   * @param string the string to split   * @param limit if specified, the maximum number of elements in the array   * @return an array of strings split around the pattern string   */  public static Value spliti(Env env,			    StringValue patternString,			    StringValue string,			    @Optional("-1") long limit)  {    return splitImpl(env, patternString, string, limit, true);  }  /**   * Split string into array by regular expression   *   * @param env the calling environment   */  private static Value splitImpl(Env env,			    StringValue patternString,			    StringValue string,			    long limit,                            boolean isCaseInsensitive)  {    try {      if (limit < 0)        limit = LONG_MAX;      // php/151c      if (isCaseInsensitive)        patternString = addDelimiters(env, patternString, "/", "/i");      else        patternString = addDelimiters(env, patternString, "/", "/");      Regexp regexp = getRegexp(env, patternString);      RegexpState regexpState = new RegexpState(env, regexp, string);      ArrayValue result = new ArrayValueImpl();      long count = 0;      int head = 0;      while (regexpState.find() && count < limit) {        StringValue value;        if (count == limit - 1) {          value = regexpState.substring(env, head);          head = string.length();        } else {          value = regexpState.substring(env, head, regexpState.start());          head = regexpState.end();        }        result.put(value);        count++;      }      if (head <= string.length() && count != limit) {        result.put(regexpState.substring(env, head));      }      return result;    } catch (IllegalRegexpException e) {      log.log(Level.FINE, e.getMessage(), e);      env.warning(e);            return BooleanValue.FALSE;    }  }  /**   * Returns an array of all the values that matched the given pattern if the   * flag no flag is passed.  Otherwise it will return an array of all the   * values that did not match.   *   * @param patternString the pattern   * @param input the array to check the pattern against   * @param flag 0 for matching and 1 for elements that do not match   * @return an array of either matching elements are non-matching elements   */  public static Value preg_grep(Env env,				StringValue patternString,				ArrayValue input,				@Optional("0") int flag)  {    try {      if (input == null)        return NullValue.NULL;      Regexp regexp = getRegexp(env, patternString);      RegexpState regexpState = new RegexpState(regexp);      ArrayValue matchArray = new ArrayValueImpl();      for (Map.Entry<Value, Value> entry : input.entrySet()) {        Value entryValue = entry.getValue();        Value entryKey = entry.getKey();        boolean found = regexpState.find(env, entryValue.toStringValue());        if (! found && flag == PREG_GREP_INVERT)          matchArray.append(entryKey, entryValue);        else if (found && flag != PREG_GREP_INVERT)          matchArray.append(entryKey, entryValue);      }      return matchArray;    } catch (IllegalRegexpException e) {      log.log(Level.FINE, e.getMessage(), e);      env.warning(e);            return BooleanValue.FALSE;    }  }  private static Regexp getRegexp(Env env,                                  StringValue rawRegexp,                                  StringValue subject)    throws IllegalRegexpException  {    return getRegexp(env, rawRegexp);  }  private static Regexp getRegexp(Env env,                                  StringValue rawRegexp)    throws IllegalRegexpException  {    Regexp regexp = _regexpCache.get(rawRegexp);    if (regexp != null)      return regexp;    regexp = new Regexp(env, rawRegexp);    _regexpCache.put(rawRegexp, regexp);    return regexp;  }    private static StringValue addDelimiters(Env env,                                           StringValue str,                                           String startDelim,                                           String endDelim)  {    StringValue sb = str.createStringBuilder();        sb = sb.appendBytes(startDelim);    sb = sb.append(str);    sb = sb.appendBytes(endDelim);        return sb;  }  private static ArrayList<Replacement>  compileReplacement(Env env, StringValue replacement, boolean isEval)  {    ArrayList<Replacement> program = new ArrayList<Replacement>();    StringBuilder text = new StringBuilder();    for (int i = 0; i < replacement.length(); i++) {      char ch = replacement.charAt(i);      if ((ch == '\\' || ch == '$') && i + 1 < replacement.length()) {        char digit;        if ('0' <= (digit = replacement.charAt(i + 1)) && digit <= '9') {          int group = digit - '0';          i++;          if (i + 1 < replacement.length()	      && '0' <= (digit = replacement.charAt(i + 1)) && digit <= '9') {            group = 10 * group + digit - '0';            i++;          }          if (text.length() > 0) {            program.add(new TextReplacement(text));          }          if (isEval)            program.add(new GroupEscapeReplacement(group));          else            program.add(new GroupReplacement(group));          text.setLength(0);        }        else if (ch == '\\') {          i++;          if (digit != '\\') {            text.append('\\');          }          text.append(digit);          // took out test for ch == '$' because must be true          //} else if (ch == '$' && digit == '{') {        } else if (digit == '{') {          i += 2;          int group = 0;          while (i < replacement.length()		 && '0' <= (digit = replacement.charAt(i)) && digit <= '9') {            group = 10 * group + digit - '0';            i++;          }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?