📄 javaregexpmodule.java
字号:
if (patternValue.isArray() && replacement.isArray()) { ArrayValue patternArray = (ArrayValue) patternValue; ArrayValue replacementArray = (ArrayValue) replacement; Iterator<Value> patternIter = patternArray.values().iterator(); Iterator<Value> replacementIter = replacementArray.values().iterator(); while (patternIter.hasNext()) { StringValue replacementStr; if (replacementIter.hasNext()) replacementStr = replacementIter.next().toStringValue(); else replacementStr = env.getEmptyString(); string = pregReplaceString(env, patternIter.next().toStringValue(), replacementStr, string, limit, countV); } } else if (patternValue.isArray()) { ArrayValue patternArray = (ArrayValue) patternValue; for (Value value : patternArray.values()) { string = pregReplaceString(env, value.toStringValue(), replacement.toStringValue(), string, limit, countV); } } else { return pregReplaceString(env, patternValue.toStringValue(), replacement.toStringValue(), string, limit, countV); } return string; } /** * replaces values using regexps and callback fun * @param env * @param patternString * @param fun * @param subject * @param limit * @param countV * @return subject with everything replaced */ private static StringValue pregReplaceCallbackImpl(Env env, StringValue patternString, Callback fun, StringValue subject, long limit, Value countV) { long numberOfMatches = 0; if (limit < 0) limit = Long.MAX_VALUE; Pattern pattern = compileRegexp(patternString); Matcher matcher = pattern.matcher(subject); StringValue result = env.createUnicodeBuilder(); int tail = 0; while (matcher.find() && numberOfMatches < limit) { // Increment countV (note: if countV != null, then it should be a Var) if ((countV != null) && (countV instanceof Var)) { long count = ((Var) countV).getRawValue().toLong(); countV.set(LongValue.create(count + 1)); } if (tail < matcher.start()) result = result.append(subject.substring(tail, matcher.start())); ArrayValue regs = new ArrayValueImpl(); for (int i = 0; i <= matcher.groupCount(); i++) { String group = matcher.group(i); if (group != null) regs.put(env.createString(group)); else regs.put(env.getEmptyString()); } Value replacement = fun.call(env, regs); result = result.append(replacement); tail = matcher.end(); numberOfMatches++; } if (tail < subject.length()) result = result.append(subject.substring(tail)); return result; } /** * Replaces values using regexps */ private static StringValue pregReplaceString(Env env, StringValue patternString, StringValue replacement, StringValue subject, long limit, Value countV) { Pattern pattern = compileRegexp(patternString); // check for e modifier in patternString int patternFlags = regexpFlags(patternString); boolean isEval = (patternFlags & PREG_REPLACE_EVAL) != 0; ArrayList<Replacement> replacementProgram = _replacementCache.get(replacement); if (replacementProgram == null) { replacementProgram = compileReplacement(env, replacement, isEval); _replacementCache.put(replacement, replacementProgram); } return pregReplaceStringImpl(env, pattern, replacementProgram, subject, limit, countV, isEval); } public static Value ereg_replace(Env env, Value pattern, Value replacement, StringValue subject) { return eregReplaceImpl(env, pattern, replacement, subject, false); } /** * Replaces values using regexps */ public static Value eregi_replace(Env env, Value pattern, Value replacement, StringValue subject) { return eregReplaceImpl(env, pattern, replacement, subject, true); } /** * Replaces values using regexps */ public static Value eregReplaceImpl(Env env, Value pattern, Value replacement, StringValue subject, boolean isCaseInsensitive) { StringValue patternStr; StringValue replacementStr; // php/1511 : error when pattern argument is null or an empty string if (pattern.length() == 0) { env.warning(L.l("empty pattern argument")); return BooleanValue.FALSE; } // php/150u : If a non-string type argument is passed // for the pattern or replacement argument, it is // converted to a string of length 1 that contains // a single character. if (pattern instanceof StringValue) { patternStr = pattern.toStringValue(); } else { patternStr = env.createString( String.valueOf((char) pattern.toLong())); } if (replacement instanceof NullValue) { replacementStr = env.getEmptyString(); } else if (replacement instanceof StringValue) { replacementStr = replacement.toStringValue(); } else { replacementStr = env.createString( String.valueOf((char) replacement.toLong())); } Pattern patternObj; if (isCaseInsensitive) { patternObj = Pattern.compile(cleanRegexp(patternStr, false), Pattern.CASE_INSENSITIVE); } else { patternObj = Pattern.compile(cleanRegexp(patternStr, false)); } ArrayList<Replacement> replacementProgram = _replacementCache.get(replacementStr); if (replacementProgram == null) { replacementProgram = compileReplacement(env, replacementStr, false); _replacementCache.put(replacementStr, replacementProgram); } return pregReplaceStringImpl(env, patternObj, replacementProgram, subject, -1, NullValue.NULL, false); } /** * Replaces values using regexps */ private static StringValue pregReplaceStringImpl(Env env, Pattern pattern, ArrayList<Replacement> replacementProgram, StringValue subject, long limit, Value countV, boolean isEval) { if (limit < 0) limit = Long.MAX_VALUE; int length = subject.length(); Matcher matcher = pattern.matcher(subject); StringValue result = null; int tail = 0; int replacementLen = replacementProgram.size(); while (matcher.find() && limit-- > 0) { if (result == null) result = subject.createStringBuilder(); // Increment countV (note: if countV != null, then it should be a Var) if ((countV != null) && (countV instanceof Var)) { countV.set(LongValue.create(countV.toLong() + 1)); } // append all text up to match if (tail < matcher.start()) result.append(subject, tail, matcher.start()); // if isEval then append replacement evaluated as PHP code // else append replacement string if (isEval) { StringValue evalString = subject.createStringBuilder(); for (int i = 0; i < replacementLen; i++) { Replacement replacement = replacementProgram.get(i); replacement.eval(evalString, subject, matcher); } try { if (evalString.length() > 0) // php/152z result.append(env.evalCode(evalString.toString())); } catch (IOException e) { throw new QuercusException(e); } } else { for (int i = 0; i < replacementLen; i++) { Replacement replacement = replacementProgram.get(i); replacement.eval(result, subject, matcher); } } tail = matcher.end(); } if (result == null) return subject; if (tail < length) result.append(subject, tail, length); return result; } /** * Loops through subject if subject is array of strings * * @param env * @param pattern * @param fun * @param subject * @param limit * @param count * @return */ public static Value preg_replace_callback(Env env, Value pattern, Callback fun, Value subject, @Optional("-1") long limit, @Optional @Reference Value count) { 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(); } } /** * Replaces values using regexps */ private static Value pregReplaceCallback(Env env, Value patternValue, Callback fun, StringValue subject, @Optional("-1") long limit, @Optional @Reference Value countV) { if (limit < 0) limit = Long.MAX_VALUE; 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) { if (limit <= 0) limit = Long.MAX_VALUE; Pattern pattern = compileRegexp(patternString); Matcher matcher = pattern.matcher(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(pattern.pattern(), matcher.groupCount()); while (matcher.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, matcher.start()); head = matcher.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 <= matcher.groupCount(); i++) { int start = matcher.start(i); int end = matcher.end(i); // Skip empty groups if (start == -1) { 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 (matcher.start(group) != -1) { break; } if (isCaptureOffset) { ArrayValue part = new ArrayValueImpl(); part.put(env.getEmptyString()); part.put(LongValue.create(startPosition)); result.put(part); } else { result.put(env.getEmptyString()); } } } if (end - start <= 0 && ! allowEmpty) { continue; } StringValue groupValue = string.substring(start, end); 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; } /** * 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 the index of the first match. * * @param env the calling environment */ public static Value split(Env env, StringValue patternString, StringValue string, @Optional("-1") long limit) { if (limit < 0) limit = Long.MAX_VALUE; String cleanRegexp = cleanRegexp(patternString, false); Pattern pattern = Pattern.compile(cleanRegexp); ArrayValue result = new ArrayValueImpl(); Matcher matcher = pattern.matcher(string); long count = 0; int head = 0; while ((matcher.find()) && (count < limit)) { StringValue value; if (count == limit - 1) { value = string.substring(head); head = string.length(); } else { value = string.substring(head, matcher.start()); head = matcher.end(); } result.put(value); count++; } if ((head <= string.length() && (count != limit))) { result.put(string.substring(head)); } return result; } /** * 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -