📄 re.java
字号:
if (m.end[0] == 0) { // handle pathological case of zero-length match index++; input.move(1); } else { input.move(m.end[0]); } if (!input.isValid()) break; } REMatch[] mset = new REMatch[all.size()]; all.copyInto(mset); return mset; } /* Implements abstract method REToken.match() */ boolean match(CharIndexed input, REMatch mymatch) { if (firstToken == null) { return next(input, mymatch); } // Note the start of this subexpression mymatch.start[subIndex] = mymatch.index; return firstToken.match(input, mymatch); } REMatch findMatch(CharIndexed input, REMatch mymatch) { if (mymatch.backtrackStack == null) mymatch.backtrackStack = new BacktrackStack(); boolean b = match(input, mymatch); if (b) { // mymatch.backtrackStack.push(new REMatch.Backtrack( // this, input, mymatch, null)); return mymatch; } return null; } /** * Returns the first match found in the input. If no match is found, * null is returned. * * @param input The input text. * @return An REMatch instance referencing the match, or null if none. */ public REMatch getMatch(Object input) { return getMatch(input,0,0); } /** * Returns the first match found in the input, beginning * the search at the specified index. If no match is found, * returns null. * * @param input The input text. * @param index The offset within the text to begin looking for a match. * @return An REMatch instance referencing the match, or null if none. */ public REMatch getMatch(Object input, int index) { return getMatch(input,index,0); } /** * Returns the first match found in the input, beginning * the search at the specified index, and using the specified * execution flags. If no match is found, returns null. * * @param input The input text. * @param index The offset index at which the search should be begin. * @param eflags The logical OR of any execution flags above. * @return An REMatch instance referencing the match, or null if none. */ public REMatch getMatch(Object input, int index, int eflags) { return getMatch(input,index,eflags,null); } /** * Returns the first match found in the input, beginning the search * at the specified index, and using the specified execution flags. * If no match is found, returns null. If a StringBuffer is * provided and is non-null, the contents of the input text from the * index to the beginning of the match (or to the end of the input, * if there is no match) are appended to the StringBuffer. * * @param input The input text. * @param index The offset index at which the search should be begin. * @param eflags The logical OR of any execution flags above. * @param buffer The StringBuffer to save pre-match text in. * @return An REMatch instance referencing the match, or null if none. */ public REMatch getMatch(Object input, int index, int eflags, StringBuffer buffer) { return getMatchImpl(makeCharIndexed(input,index),index,eflags,buffer); } REMatch getMatchImpl(CharIndexed input, int anchor, int eflags, StringBuffer buffer) { boolean tryEntireMatch = ((eflags & REG_TRY_ENTIRE_MATCH) != 0); RE re = (tryEntireMatch ? (RE) this.clone() : this); if (tryEntireMatch) { re.chain(new RETokenEnd(0, null)); } // Create a new REMatch to hold results REMatch mymatch = new REMatch(numSubs, anchor, eflags); do { // Optimization: check if anchor + minimumLength > length if (minimumLength == 0 || input.charAt(minimumLength-1) != CharIndexed.OUT_OF_BOUNDS) { if (re.match(input, mymatch)) { REMatch best = mymatch; // We assume that the match that coms first is the best. // And the following "The longer, the better" rule has // been commented out. The longest is not neccesarily // the best. For example, "a" out of "aaa" is the best // match for /a+?/. /* // Find best match of them all to observe leftmost longest while ((mymatch = mymatch.next) != null) { if (mymatch.index > best.index) { best = mymatch; } } */ best.end[0] = best.index; best.finish(input); return best; } } mymatch.clear(++anchor); // Append character to buffer if needed if (buffer != null && input.charAt(0) != CharIndexed.OUT_OF_BOUNDS) { buffer.append(input.charAt(0)); } } while (input.move(1)); // Special handling at end of input for e.g. "$" if (minimumLength == 0) { if (match(input, mymatch)) { mymatch.finish(input); return mymatch; } } return null; } /** * Returns an REMatchEnumeration that can be used to iterate over the * matches found in the input text. * * @param input The input text. * @return A non-null REMatchEnumeration instance. */ public REMatchEnumeration getMatchEnumeration(Object input) { return getMatchEnumeration(input,0,0); } /** * Returns an REMatchEnumeration that can be used to iterate over the * matches found in the input text. * * @param input The input text. * @param index The offset index at which the search should be begin. * @return A non-null REMatchEnumeration instance, with its input cursor * set to the index position specified. */ public REMatchEnumeration getMatchEnumeration(Object input, int index) { return getMatchEnumeration(input,index,0); } /** * Returns an REMatchEnumeration that can be used to iterate over the * matches found in the input text. * * @param input The input text. * @param index The offset index at which the search should be begin. * @param eflags The logical OR of any execution flags above. * @return A non-null REMatchEnumeration instance, with its input cursor * set to the index position specified. */ public REMatchEnumeration getMatchEnumeration(Object input, int index, int eflags) { return new REMatchEnumeration(this,makeCharIndexed(input,index),index,eflags); } /** * Substitutes the replacement text for the first match found in the input. * * @param input The input text. * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto). * @return A String interpolating the substituted text. * @see REMatch#substituteInto */ public String substitute(Object input,String replace) { return substitute(input,replace,0,0); } /** * Substitutes the replacement text for the first match found in the input * beginning at the specified index position. Specifying an index * effectively causes the regular expression engine to throw away the * specified number of characters. * * @param input The input text. * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto). * @param index The offset index at which the search should be begin. * @return A String containing the substring of the input, starting * at the index position, and interpolating the substituted text. * @see REMatch#substituteInto */ public String substitute(Object input,String replace,int index) { return substitute(input,replace,index,0); } /** * Substitutes the replacement text for the first match found in the input * string, beginning at the specified index position and using the * specified execution flags. * * @param input The input text. * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto). * @param index The offset index at which the search should be begin. * @param eflags The logical OR of any execution flags above. * @return A String containing the substring of the input, starting * at the index position, and interpolating the substituted text. * @see REMatch#substituteInto */ public String substitute(Object input,String replace,int index,int eflags) { return substituteImpl(makeCharIndexed(input,index),replace,index,eflags); } private String substituteImpl(CharIndexed input,String replace,int index,int eflags) { StringBuffer buffer = new StringBuffer(); REMatch m = getMatchImpl(input,index,eflags,buffer); if (m==null) return buffer.toString(); buffer.append(getReplacement(replace, m, eflags)); if (input.move(m.end[0])) { do { buffer.append(input.charAt(0)); } while (input.move(1)); } return buffer.toString(); } /** * Substitutes the replacement text for each non-overlapping match found * in the input text. * * @param input The input text. * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto). * @return A String interpolating the substituted text. * @see REMatch#substituteInto */ public String substituteAll(Object input,String replace) { return substituteAll(input,replace,0,0); } /** * Substitutes the replacement text for each non-overlapping match found * in the input text, starting at the specified index. * * If the regular expression allows the empty string to match, it will * substitute matches at all positions except the end of the input. * * @param input The input text. * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto). * @param index The offset index at which the search should be begin. * @return A String containing the substring of the input, starting * at the index position, and interpolating the substituted text. * @see REMatch#substituteInto */ public String substituteAll(Object input,String replace,int index) { return substituteAll(input,replace,index,0); } /** * Substitutes the replacement text for each non-overlapping match found * in the input text, starting at the specified index and using the * specified execution flags. * * @param input The input text. * @param replace The replacement text, which may contain $x metacharacters (see REMatch.substituteInto). * @param index The offset index at which the search should be begin. * @param eflags The logical OR of any execution flags above. * @return A String containing the substring of the input, starting * at the index position, and interpolating the substituted text. * @see REMatch#substituteInto */ public String substituteAll(Object input,String replace,int index,int eflags) { return substituteAllImpl(makeCharIndexed(input,index),replace,index,eflags); } private String substituteAllImpl(CharIndexed input,String replace,int index,int eflags) { StringBuffer buffer = new StringBuffer(); REMatch m; while ((m = getMatchImpl(input,index,eflags,buffer)) != null) { buffer.append(getReplacement(replace, m, eflags)); index = m.getEndIndex(); if (m.end[0] == 0) { char ch = input.charAt(0); if (ch != CharIndexed.OUT_OF_BOUNDS) buffer.append(ch); input.move(1); } else { input.move(m.end[0]); } if (!input.isValid()) break; } return buffer.toString(); } public static String getReplacement(String replace, REMatch m, int eflags) { if ((eflags & REG_NO_INTERPOLATE) > 0) return replace; else { if ((eflags & REG_REPLACE_USE_BACKSLASHESCAPE) > 0) { StringBuffer sb = new StringBuffer(); int l = replace.length(); for (int i = 0; i < l; i++) { char c = replace.charAt(i); switch(c) { case '\\': i++; // Let StringIndexOutOfBoundsException be thrown. sb.append(replace.charAt(i)); break; case '$': int i1 = i + 1; while (i1 < replace.length() && Character.isDigit(replace.charAt(i1))) i1++; sb.append(m.substituteInto(replace.substring(i, i1))); i = i1 - 1; break; default: sb.append(c); } } return sb.toString(); } else return m.substituteInto(replace); } } /* Helper function for constructor */ private void addToken(REToken next) { if (next == null) return; minimumLength += next.getMinimumLength(); int nmax = next.getMaximumLength(); if (nmax < Integer.MAX_VALUE && maximumLength < Integer.MAX_VALUE) maximumLength += nmax; else maximumLength = Integer.MAX_VALUE; if (firstToken == null) { lastToken = firstToken = next; } else { // if chain returns false, it "rejected" the token due to // an optimization, and next was combined with lastToken if (lastToken.chain(next)) { lastToken = next; } } } private static REToken setRepeated(REToken current, int min, int max, int index) throws REException { if (current == null) throw new REException(getLocalizedMessage("repeat.no.token"),REException.REG_BADRPT,index); return new RETokenRepeated(current.subIndex,current,min,max); } private static int getPosixSet(char[] pattern,int index,StringBuffer buf) { // Precondition: pattern[index-1] == ':' // we will return pos
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -