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 + -
显示快捷键?