summaryrefslogtreecommitdiffstats
path: root/regex
diff options
context:
space:
mode:
authorJesse Wilson <jessewilson@google.com>2009-09-14 15:30:14 -0700
committerJesse Wilson <jessewilson@google.com>2009-09-14 15:30:14 -0700
commit77d58e2a1577a4992f4d81e9ca2807f7533725c6 (patch)
tree14cb10317acb854fee0a4aa2b7944a22aaa02e6b /regex
parent521d96b9155899a5cc94ba942d018e5cca465512 (diff)
downloadlibcore-77d58e2a1577a4992f4d81e9ca2807f7533725c6.zip
libcore-77d58e2a1577a4992f4d81e9ca2807f7533725c6.tar.gz
libcore-77d58e2a1577a4992f4d81e9ca2807f7533725c6.tar.bz2
Update regex to Harmony r802921.
Notable changes: - Reordered methods to be consistent with Harmony. Although our implementations are significantly different, this will make it easier to track Javadoc and signature changes. - Some unchecked exceptions removed from method signatures - Changed StringBuffer use to StringBuilder - Changed PatternSyntaxException description field to 'desc' for serialization compatibility. commit deba65caf92e9c5b77b29bcf9dcb26d637af90cb Merge: b239d4a 457c6cc Author: Jesse Wilson <jessewilson@google.com> Date: Wed Aug 12 09:23:58 2009 -0700 Merge branch 'regex_802921' into regex_dalvik Conflicts: libcore/regex/.classpath libcore/regex/.settings/org.eclipse.jdt.core.prefs libcore/regex/build.xml libcore/regex/src/main/java/java/util/regex/AbstractCharClass.java libcore/regex/src/main/java/java/util/regex/AbstractSet.java libcore/regex/src/main/java/java/util/regex/CIDecomposedCharSet.java libcore/regex/src/main/java/java/util/regex/CharClass.java libcore/regex/src/main/java/java/util/regex/DecomposedCharSet.java libcore/regex/src/main/java/java/util/regex/IntArrHash.java libcore/regex/src/main/java/java/util/regex/JointSet.java libcore/regex/src/main/java/java/util/regex/Lexer.java libcore/regex/src/main/java/java/util/regex/MatchResult.java libcore/regex/src/main/java/java/util/regex/Matcher.java libcore/regex/src/main/java/java/util/regex/Pattern.java libcore/regex/src/main/java/java/util/regex/PatternSyntaxException.java libcore/regex/src/main/java/java/util/regex/SequenceSet.java libcore/regex/src/main/java/java/util/regex/UCIDecomposedCharSet.java libcore/regex/src/main/java/java/util/regex/UCISequenceSet.java libcore/regex/src/main/java/org/apache/harmony/regex/internal/nls/messages.properties libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/Matcher2Test.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/MatcherTest.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/ModeTest.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/Pattern2Test.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/PatternErrorTest.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/PatternSyntaxExceptionTest.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/PatternTest.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/ReplaceTest.java libcore/regex/src/test/java/org/apache/harmony/tests/java/util/regex/SplitTest.java commit b239d4a17905f9e0b609eeaa12de9dfba433c44a Author: Jesse Wilson <jessewilson@google.com> Date: Wed Aug 12 08:37:21 2009 -0700 Dalvik Regex commit 457c6cca0629f20b118cd128353439763e40fe9e Author: Jesse Wilson <jessewilson@google.com> Date: Wed Aug 12 08:36:40 2009 -0700 Regex 802921 commit 51f4e67d71a8f92d8efa073fab32c540f6015594 Author: Jesse Wilson <jessewilson@google.com> Date: Wed Aug 12 08:34:57 2009 -0700 Regex 527399
Diffstat (limited to 'regex')
-rw-r--r--regex/src/main/java/java/util/regex/MatchResult.java67
-rw-r--r--regex/src/main/java/java/util/regex/Matcher.java752
-rw-r--r--regex/src/main/java/java/util/regex/Pattern.java355
-rw-r--r--regex/src/main/java/java/util/regex/PatternSyntaxException.java56
4 files changed, 567 insertions, 663 deletions
diff --git a/regex/src/main/java/java/util/regex/MatchResult.java b/regex/src/main/java/java/util/regex/MatchResult.java
index fa67ba6..76c17a8 100644
--- a/regex/src/main/java/java/util/regex/MatchResult.java
+++ b/regex/src/main/java/java/util/regex/MatchResult.java
@@ -1,17 +1,18 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
*
- * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://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.
+ * 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 java.util.regex;
@@ -22,91 +23,75 @@ package java.util.regex;
* pair of parentheses in the regular expression and an additional group for
* the whole regular expression. The start, end, and contents of each group
* can be queried.
- *
+ *
* @see Matcher
* @see Matcher#toMatchResult()
- *
- * @since Android 1.0
*/
public interface MatchResult {
/**
* Returns the index of the first character following the text that matched
- * the whole regular expression.
- *
+ * the whole regular expression.
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int end();
/**
* Returns the index of the first character following the text that matched
* a given group.
- *
+ *
* @param group
* the group, ranging from 0 to groupCount() - 1, with 0
* representing the whole pattern.
- *
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int end(int group);
/**
- * Returns the text that matched the whole regular expression.
- *
+ * Returns the text that matched the whole regular expression.
+ *
* @return the text.
- *
- * @since Android 1.0
*/
String group();
/**
* Returns the text that matched a given group of the regular expression.
- *
+ *
* @param group
* the group, ranging from 0 to groupCount() - 1, with 0
* representing the whole pattern.
- *
+ *
* @return the text that matched the group.
- *
- * @since Android 1.0
*/
String group(int group);
/**
* Returns the number of groups in the result, which is always equal to
* the number of groups in the original regular expression.
- *
+ *
* @return the number of groups.
- *
- * @since Android 1.0
*/
int groupCount();
/**
* Returns the index of the first character of the text that matched
- * the whole regular expression.
- *
+ * the whole regular expression.
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int start();
/**
* Returns the index of the first character of the text that matched a given
* group.
- *
+ *
* @param group
* the group, ranging from 0 to groupCount() - 1, with 0
* representing the whole pattern.
- *
+ *
* @return the character index.
- *
- * @since Android 1.0
*/
int start(int group);
}
diff --git a/regex/src/main/java/java/util/regex/Matcher.java b/regex/src/main/java/java/util/regex/Matcher.java
index e3e4874..be5c782 100644
--- a/regex/src/main/java/java/util/regex/Matcher.java
+++ b/regex/src/main/java/java/util/regex/Matcher.java
@@ -44,8 +44,6 @@ import com.ibm.icu4jni.regex.NativeRegEx;
* {@code Pattern} was successful and at which position the next attempt would
* resume the search. Depending on the application's needs, it may become
* necessary to explicitly {@link #reset()} this state from time to time.
- *
- * @since Android 1.0
*/
public final class Matcher implements MatchResult {
@@ -128,39 +126,99 @@ public final class Matcher implements MatchResult {
}
/**
+ * Appends a literal part of the input plus a replacement for the current
+ * match to a given {@link StringBuffer}. The literal part is exactly the
+ * part of the input between the previous match and the current match. The
+ * method can be used in conjunction with {@link #find()} and
+ * {@link #appendTail(StringBuffer)} to walk through the input and replace
+ * all occurrences of the {@code Pattern} with something else.
+ *
+ * @param buffer
+ * the {@code StringBuffer} to append to.
+ * @param replacement
+ * the replacement text.
+ * @return the {@code Matcher} itself.
+ * @throws IllegalStateException
+ * if no successful match has been made.
+ */
+ public Matcher appendReplacement(StringBuffer buffer, String replacement) {
+ buffer.append(input.substring(appendPos, start()));
+ appendEvaluated(buffer, replacement);
+ appendPos = end();
+
+ return this;
+ }
+
+ /**
+ * Internal helper method to append a given string to a given string buffer.
+ * If the string contains any references to groups, these are replaced by
+ * the corresponding group's contents.
+ *
+ * @param buffer
+ * the string buffer.
+ * @param s
+ * the string to append.
+ */
+ private void appendEvaluated(StringBuffer buffer, String s) {
+ boolean escape = false;
+ boolean dollar = false;
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' && !escape) {
+ escape = true;
+ } else if (c == '$' && !escape) {
+ dollar = true;
+ } else if (c >= '0' && c <= '9' && dollar) {
+ buffer.append(group(c - '0'));
+ dollar = false;
+ } else {
+ buffer.append(c);
+ dollar = false;
+ escape = false;
+ }
+ }
+
+ // This seemingly stupid piece of code reproduces a JDK bug.
+ if (escape) {
+ throw new ArrayIndexOutOfBoundsException(s.length());
+ }
+ }
+
+ /**
* Resets the Matcher. A new input sequence and a new region can be
* specified. Results of a previous find get lost. The next attempt to find
* an occurrence of the Pattern in the string will start at the beginning of
* the region. This is the internal version of reset() to which the several
* public versions delegate.
- *
+ *
* @param input
* the input sequence.
* @param start
* the start of the region.
* @param end
* the end of the region.
- *
+ *
* @return the matcher itself.
*/
private Matcher reset(CharSequence input, int start, int end) {
if (input == null) {
throw new IllegalArgumentException();
}
-
- if (start < 0 || end < 0 || start > input.length() ||
+
+ if (start < 0 || end < 0 || start > input.length() ||
end > input.length() || start > end) {
throw new IllegalArgumentException();
}
// Maybe should have a reset() here, but it makes thing worse...
// NativeRegEx.reset(nativePattern, 0);
-
+
if (!input.equals(this.input)) {
this.input = input.toString();
-
+
NativeRegEx.setText(nativePattern, this.input);
-
+
regionStart = 0;
regionEnd = input.length();
}
@@ -176,22 +234,8 @@ public final class Matcher implements MatchResult {
matchFound = false;
findPos = regionStart;
appendPos = 0;
-
- return this;
- }
- /**
- * Resets the {@code Matcher}. This results in the region being set to the
- * whole input. Results of a previous find get lost. The next attempt to
- * find an occurrence of the {@link Pattern} in the string will start at the
- * beginning of the input.
- *
- * @return the {@code Matcher} itself.
- *
- * @since Android 1.0
- */
- public Matcher reset() {
- return reset(input, 0, input.length());
+ return this;
}
/**
@@ -204,73 +248,24 @@ public final class Matcher implements MatchResult {
* the new input sequence.
*
* @return the {@code Matcher} itself.
- *
- * @since Android 1.0
*/
public Matcher reset(CharSequence input) {
return reset(input, 0, input.length());
}
/**
- * Sets a new pattern for the {@code Matcher}. Results of a previous find
- * get lost. The next attempt to find an occurrence of the {@link Pattern}
- * in the string will start at the beginning of the input.
- *
- * @param pattern
- * the new {@code Pattern}.
- *
+ * Resets the {@code Matcher}. This results in the region being set to the
+ * whole input. Results of a previous find get lost. The next attempt to
+ * find an occurrence of the {@link Pattern} in the string will start at the
+ * beginning of the input.
+ *
* @return the {@code Matcher} itself.
- *
- * @since Android 1.0
*/
- public Matcher usePattern(Pattern pattern) {
- if (pattern == null) {
- throw new IllegalArgumentException();
- }
-
- this.pattern = pattern;
-
- if (nativePattern != 0) {
- NativeRegEx.close(nativePattern);
- }
- nativePattern = NativeRegEx.clone(pattern.mNativePattern);
-
- if (input != null) {
- NativeRegEx.setText(nativePattern, input);
- NativeRegEx.setRegion(nativePattern, regionStart, regionEnd);
- NativeRegEx.useAnchoringBounds(nativePattern, anchoringBounds);
- NativeRegEx.useTransparentBounds(nativePattern, transparentBounds);
- }
-
- matchOffsets = new int[(this.pattern.mGroupCount + 1) * 2];
- matchFound = false;
- return this;
- }
-
- /**
- * Returns the {@link Pattern} instance used inside this matcher.
- *
- * @return the {@code Pattern} instance.
- *
- * @since Android 1.0
- */
- public Pattern pattern() {
- return pattern;
+ public Matcher reset() {
+ return reset(input, 0, input.length());
}
/**
- * Returns the number of groups in the results, which is always equal to
- * the number of groups in the original regular expression.
- *
- * @return the number of groups.
- *
- * @since Android 1.0
- */
- public int groupCount() {
- return pattern.mGroupCount;
- }
-
- /**
* Resets this matcher and sets a region. Only characters inside the region
* are considered for a match.
*
@@ -279,109 +274,150 @@ public final class Matcher implements MatchResult {
* @param end
* the first character after the end of the region.
* @return the {@code Matcher} itself.
- * @since Android 1.0
*/
public Matcher region(int start, int end) {
return reset(input, start, end);
}
+
/**
- * Returns this matcher's region start, that is, the first character that is
- * considered for a match.
- *
- * @return the start of the region.
- * @since Android 1.0
+ * Appends the (unmatched) remainder of the input to the given
+ * {@link StringBuffer}. The method can be used in conjunction with
+ * {@link #find()} and {@link #appendReplacement(StringBuffer, String)} to
+ * walk through the input and replace all matches of the {@code Pattern}
+ * with something else.
+ *
+ * @param buffer
+ * the {@code StringBuffer} to append to.
+ * @return the {@code StringBuffer}.
+ * @throws IllegalStateException
+ * if no successful match has been made.
*/
- public int regionStart() {
- return regionStart;
+ public StringBuffer appendTail(StringBuffer buffer) {
+ if (appendPos < regionEnd) {
+ buffer.append(input.substring(appendPos, regionEnd));
+ }
+
+ return buffer;
}
/**
- * Returns this matcher's region end, that is, the first character that is
- * not considered for a match.
- *
- * @return the end of the region.
- * @since Android 1.0
+ * Replaces the first occurrence of this matcher's pattern in the input with
+ * a given string.
+ *
+ * @param replacement
+ * the replacement text.
+ * @return the modified input string.
*/
- public int regionEnd() {
- return regionEnd;
+ public String replaceFirst(String replacement) {
+ StringBuffer buffer = new StringBuffer(input.length());
+
+ findPos = 0;
+ appendPos = 0;
+ matchFound = false;
+ searching = false;
+
+ if (find()) {
+ appendReplacement(buffer, replacement);
+ }
+
+ return appendTail(buffer).toString();
}
/**
- * Determines whether this matcher has anchoring bounds enabled or not. When
- * anchoring bounds are enabled, the start and end of the input match the
- * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
- * by default.
- *
- * @param value
- * the new value for anchoring bounds.
- * @return the {@code Matcher} itself.
- * @since Android 1.0
+ * Replaces all occurrences of this matcher's pattern in the input with a
+ * given string.
+ *
+ * @param replacement
+ * the replacement text.
+ * @return the modified input string.
*/
- public Matcher useAnchoringBounds(boolean value) {
- anchoringBounds = value;
- NativeRegEx.useAnchoringBounds(nativePattern, value);
- return this;
+ public String replaceAll(String replacement) {
+ StringBuffer buffer = new StringBuffer(input.length());
+
+ findPos = 0;
+ appendPos = 0;
+ matchFound = false;
+ searching = false;
+
+ while (find()) {
+ appendReplacement(buffer, replacement);
+ }
+
+ return appendTail(buffer).toString();
}
-
+
/**
- * Indicates whether this matcher has anchoring bounds enabled. When
- * anchoring bounds are enabled, the start and end of the input match the
- * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
- * by default.
- *
- * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
- * @since Android 1.0
+ * Returns the {@link Pattern} instance used inside this matcher.
+ *
+ * @return the {@code Pattern} instance.
*/
- public boolean hasAnchoringBounds() {
- return anchoringBounds;
+ public Pattern pattern() {
+ return pattern;
}
/**
- * Determines whether this matcher has transparent bounds enabled or not.
- * When transparent bounds are enabled, the parts of the input outside the
- * region are subject to lookahead and lookbehind, otherwise they are not.
- * Transparent bounds are disabled by default.
- *
- * @param value
- * the new value for transparent bounds.
- * @return the {@code Matcher} itself.
- * @since Android 1.0
+ * Returns the text that matched a given group of the regular expression.
+ *
+ * @param group
+ * the group, ranging from 0 to groupCount() - 1, with 0
+ * representing the whole pattern.
+ * @return the text that matched the group.
+ * @throws IllegalStateException
+ * if no successful match has been made.
*/
- public Matcher useTransparentBounds(boolean value) {
- transparentBounds = value;
- NativeRegEx.useTransparentBounds(nativePattern, value);
- return this;
+ public String group(int group) {
+ ensureMatch();
+ int from = matchOffsets[group * 2];
+ int to = matchOffsets[(group * 2) + 1];
+ if (from == -1 || to == -1) {
+ return null;
+ } else {
+ return input.substring(from, to);
+ }
}
-
+
/**
- * Indicates whether this matcher has transparent bounds enabled. When
- * transparent bounds are enabled, the parts of the input outside the region
- * are subject to lookahead and lookbehind, otherwise they are not.
- * Transparent bounds are disabled by default.
- *
- * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
- * @since Android 1.0
+ * Returns the text that matched the whole regular expression.
+ *
+ * @return the text.
+ * @throws IllegalStateException
+ * if no successful match has been made.
*/
- public boolean hasTransparentBounds() {
- return transparentBounds;
+ public String group() {
+ return group(0);
}
-
+
/**
- * Makes sure that a successful match has been made. Is invoked internally
- * from various places in the class.
- *
- * @throws IllegalStateException
- * if no successful match has been made.
- *
- * @since Android 1.0
+ * Returns the next occurrence of the {@link Pattern} in the input. The
+ * method starts the search from the given character in the input.
+ *
+ * @param start
+ * The index in the input at which the find operation is to
+ * begin. If this is less than the start of the region, it is
+ * automatically adjusted to that value. If it is beyond the end
+ * of the region, the method will fail.
+ * @return true if (and only if) a match has been found.
*/
- private void ensureMatch() throws IllegalStateException {
- if (!matchFound) {
- throw new IllegalStateException("No successful match so far");
+ public boolean find(int start) {
+ findPos = start;
+
+ if (findPos < regionStart) {
+ findPos = regionStart;
+ } else if (findPos >= regionEnd) {
+ matchFound = false;
+ return false;
}
+
+ matchFound = NativeRegEx.find(nativePattern, findPos);
+ if (matchFound) {
+ NativeRegEx.startEnd(nativePattern, matchOffsets);
+ findPos = matchOffsets[1];
+ }
+
+ return matchFound;
}
-
+
/**
* Returns the next occurrence of the {@link Pattern} in the input. If a
* previous match was successful, the method continues the search from the
@@ -389,7 +425,6 @@ public final class Matcher implements MatchResult {
* either from the region start (if one has been set), or from position 0.
*
* @return true if (and only if) a match has been found.
- * @since Android 1.0
*/
public boolean find() {
if (!searching) {
@@ -408,34 +443,35 @@ public final class Matcher implements MatchResult {
}
/**
- * Returns the next occurrence of the {@link Pattern} in the input. The
- * method starts the search from the given character in the input.
- *
- * @param start
- * The index in the input at which the find operation is to
- * begin. If this is less than the start of the region, it is
- * automatically adjusted to that value. If it is beyond the end
- * of the region, the method will fail.
- * @return true if (and only if) a match has been found.
- * @since Android 1.0
+ * Returns the index of the first character of the text that matched a given
+ * group.
+ *
+ * @param group
+ * the group, ranging from 0 to groupCount() - 1, with 0
+ * representing the whole pattern.
+ * @return the character index.
+ * @throws IllegalStateException
+ * if no successful match has been made.
*/
- public boolean find(int start) {
- findPos = start;
-
- if (findPos < regionStart) {
- findPos = regionStart;
- } else if (findPos >= regionEnd) {
- matchFound = false;
- return false;
- }
-
- matchFound = NativeRegEx.find(nativePattern, findPos);
- if (matchFound) {
- NativeRegEx.startEnd(nativePattern, matchOffsets);
- findPos = matchOffsets[1];
- }
-
- return matchFound;
+ public int start(int group) throws IllegalStateException {
+ ensureMatch();
+ return matchOffsets[group * 2];
+ }
+
+ /**
+ * Returns the index of the first character following the text that matched
+ * a given group.
+ *
+ * @param group
+ * the group, ranging from 0 to groupCount() - 1, with 0
+ * representing the whole pattern.
+ * @return the character index.
+ * @throws IllegalStateException
+ * if no successful match has been made.
+ */
+ public int end(int group) {
+ ensureMatch();
+ return matchOffsets[(group * 2) + 1];
}
/**
@@ -444,8 +480,6 @@ public final class Matcher implements MatchResult {
*
* @return true if (and only if) the {@code Pattern} matches the entire
* region.
- *
- * @since Android 1.0
*/
public boolean matches() {
matchFound = NativeRegEx.matches(nativePattern, -1);
@@ -458,13 +492,34 @@ public final class Matcher implements MatchResult {
}
/**
+ * Returns a replacement string for the given one that has all backslashes
+ * and dollar signs escaped.
+ *
+ * @param s
+ * the input string.
+ * @return the input string, with all backslashes and dollar signs having
+ * been escaped.
+ */
+ public static String quoteReplacement(String s) {
+ StringBuffer buffer = new StringBuffer(s.length());
+
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '\\' || c == '$') {
+ buffer.append('\\');
+ }
+ buffer.append(c);
+ }
+
+ return buffer.toString();
+ }
+
+ /**
* Tries to match the {@link Pattern}, starting from the beginning of the
* region (or the beginning of the input, if no region has been set).
* Doesn't require the {@code Pattern} to match against the whole region.
*
* @return true if (and only if) the {@code Pattern} matches.
- *
- * @since Android 1.0
*/
public boolean lookingAt() {
matchFound = NativeRegEx.lookingAt(nativePattern, -1);
@@ -483,27 +538,19 @@ public final class Matcher implements MatchResult {
* @return the character index.
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
- public int start() throws IllegalStateException {
+ public int start() {
return start(0);
}
/**
- * Returns the index of the first character of the text that matched a given
- * group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the character index.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
+ * Returns the number of groups in the results, which is always equal to
+ * the number of groups in the original regular expression.
+ *
+ * @return the number of groups.
*/
- public int start(int group) throws IllegalStateException {
- ensureMatch();
- return matchOffsets[group * 2];
+ public int groupCount() {
+ return pattern.mGroupCount;
}
/**
@@ -513,255 +560,166 @@ public final class Matcher implements MatchResult {
* @return the character index.
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
public int end() {
return end(0);
}
/**
- * Returns the index of the first character following the text that matched
- * a given group.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the character index.
+ * Converts the current match into a separate {@link MatchResult} instance
+ * that is independent from this matcher. The new object is unaffected when
+ * the state of this matcher changes.
+ *
+ * @return the new {@code MatchResult}.
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
- public int end(int group) {
+ public MatchResult toMatchResult() {
ensureMatch();
- return matchOffsets[(group * 2) + 1];
+ return new MatchResultImpl(input, matchOffsets);
}
/**
- * Returns the text that matched the whole regular expression.
- *
- * @return the text.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
+ * Determines whether this matcher has anchoring bounds enabled or not. When
+ * anchoring bounds are enabled, the start and end of the input match the
+ * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
+ * by default.
+ *
+ * @param value
+ * the new value for anchoring bounds.
+ * @return the {@code Matcher} itself.
*/
- public String group() {
- return group(0);
+ public Matcher useAnchoringBounds(boolean value) {
+ anchoringBounds = value;
+ NativeRegEx.useAnchoringBounds(nativePattern, value);
+ return this;
}
/**
- * Returns the text that matched a given group of the regular expression.
- *
- * @param group
- * the group, ranging from 0 to groupCount() - 1, with 0
- * representing the whole pattern.
- * @return the text that matched the group.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
+ * Indicates whether this matcher has anchoring bounds enabled. When
+ * anchoring bounds are enabled, the start and end of the input match the
+ * '^' and '$' meta-characters, otherwise not. Anchoring bounds are enabled
+ * by default.
+ *
+ * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
*/
- public String group(int group) {
- ensureMatch();
- int from = matchOffsets[group * 2];
- int to = matchOffsets[(group * 2) + 1];
- if (from == -1 || to == -1) {
- return null;
- } else {
- return input.substring(from, to);
- }
+ public boolean hasAnchoringBounds() {
+ return anchoringBounds;
}
/**
- * Indicates whether the last match hit the end of the input.
- *
- * @return true if (and only if) the last match hit the end of the input.
- * @since Android 1.0
- */
- public boolean hitEnd() {
- return NativeRegEx.hitEnd(nativePattern);
- }
-
- /**
- * Indicates whether more input might change a successful match into an
- * unsuccessful one.
- *
- * @return true if (and only if) more input might change a successful match
- * into an unsuccessful one.
- * @since Android 1.0
+ * Determines whether this matcher has transparent bounds enabled or not.
+ * When transparent bounds are enabled, the parts of the input outside the
+ * region are subject to lookahead and lookbehind, otherwise they are not.
+ * Transparent bounds are disabled by default.
+ *
+ * @param value
+ * the new value for transparent bounds.
+ * @return the {@code Matcher} itself.
*/
- public boolean requireEnd() {
- return NativeRegEx.requireEnd(nativePattern);
+ public Matcher useTransparentBounds(boolean value) {
+ transparentBounds = value;
+ NativeRegEx.useTransparentBounds(nativePattern, value);
+ return this;
}
-
+
/**
- * Converts the current match into a separate {@link MatchResult} instance
- * that is independent from this matcher. The new object is unaffected when
- * the state of this matcher changes.
- *
- * @return the new {@code MatchResult}.
+ * Makes sure that a successful match has been made. Is invoked internally
+ * from various places in the class.
+ *
* @throws IllegalStateException
* if no successful match has been made.
- * @since Android 1.0
*/
- public MatchResult toMatchResult() {
- ensureMatch();
- return new MatchResultImpl(input, matchOffsets);
+ private void ensureMatch() {
+ if (!matchFound) {
+ throw new IllegalStateException("No successful match so far");
+ }
}
/**
- * Appends a literal part of the input plus a replacement for the current
- * match to a given {@link StringBuffer}. The literal part is exactly the
- * part of the input between the previous match and the current match. The
- * method can be used in conjunction with {@link #find()} and
- * {@link #appendTail(StringBuffer)} to walk through the input and replace
- * all occurrences of the {@code Pattern} with something else.
- *
- * @param buffer
- * the {@code StringBuffer} to append to.
- * @param replacement
- * the replacement text.
- * @return the {@code Matcher} itself.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
+ * Indicates whether this matcher has transparent bounds enabled. When
+ * transparent bounds are enabled, the parts of the input outside the region
+ * are subject to lookahead and lookbehind, otherwise they are not.
+ * Transparent bounds are disabled by default.
+ *
+ * @return true if (and only if) the {@code Matcher} uses anchoring bounds.
*/
- public Matcher appendReplacement(StringBuffer buffer, String replacement)
- throws IllegalStateException {
-
- buffer.append(input.substring(appendPos, start()));
- appendEvaluated(buffer, replacement);
- appendPos = end();
-
- return this;
+ public boolean hasTransparentBounds() {
+ return transparentBounds;
}
/**
- * Appends the (unmatched) remainder of the input to the given
- * {@link StringBuffer}. The method can be used in conjunction with
- * {@link #find()} and {@link #appendReplacement(StringBuffer, String)} to
- * walk through the input and replace all matches of the {@code Pattern}
- * with something else.
- *
- * @param buffer
- * the {@code StringBuffer} to append to.
- * @return the {@code StringBuffer}.
- * @throws IllegalStateException
- * if no successful match has been made.
- * @since Android 1.0
+ * Returns this matcher's region start, that is, the first character that is
+ * considered for a match.
+ *
+ * @return the start of the region.
*/
- public StringBuffer appendTail(StringBuffer buffer) {
- if (appendPos < regionEnd) {
- buffer.append(input.substring(appendPos, regionEnd));
- }
-
- return buffer;
+ public int regionStart() {
+ return regionStart;
}
/**
- * Internal helper method to append a given string to a given string buffer.
- * If the string contains any references to groups, these are replaced by
- * the corresponding group's contents.
- *
- * @param buffer
- * the string buffer.
- * @param s
- * the string to append.
+ * Returns this matcher's region end, that is, the first character that is
+ * not considered for a match.
+ *
+ * @return the end of the region.
*/
- private void appendEvaluated(StringBuffer buffer, String s) {
- boolean escape = false;
- boolean dollar = false;
-
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '\\' && !escape) {
- escape = true;
- } else if (c == '$' && !escape) {
- dollar = true;
- } else if (c >= '0' && c <= '9' && dollar) {
- buffer.append(group(c - '0'));
- dollar = false;
- } else {
- buffer.append(c);
- dollar = false;
- escape = false;
- }
- }
-
- // This seemingly stupid piece of code reproduces a JDK bug.
- if (escape) {
- throw new ArrayIndexOutOfBoundsException(s.length());
- }
+ public int regionEnd() {
+ return regionEnd;
}
-
+
/**
- * Replaces all occurrences of this matcher's pattern in the input with a
- * given string.
+ * Indicates whether more input might change a successful match into an
+ * unsuccessful one.
*
- * @param replacement
- * the replacement text.
- * @return the modified input string.
- * @since Android 1.0
+ * @return true if (and only if) more input might change a successful match
+ * into an unsuccessful one.
*/
- public String replaceAll(String replacement) {
- StringBuffer buffer = new StringBuffer(input.length());
-
- findPos = 0;
- appendPos = 0;
- matchFound = false;
- searching = false;
-
- while (find()) {
- appendReplacement(buffer, replacement);
- }
-
- return appendTail(buffer).toString();
+ public boolean requireEnd() {
+ return NativeRegEx.requireEnd(nativePattern);
}
/**
- * Replaces the first occurrence of this matcher's pattern in the input with
- * a given string.
- *
- * @param replacement
- * the replacement text.
- * @return the modified input string.
- * @since Android 1.0
+ * Indicates whether the last match hit the end of the input.
+ *
+ * @return true if (and only if) the last match hit the end of the input.
*/
- public String replaceFirst(String replacement) {
- StringBuffer buffer = new StringBuffer(input.length());
-
- findPos = 0;
- appendPos = 0;
- matchFound = false;
- searching = false;
-
- if (find()) {
- appendReplacement(buffer, replacement);
- }
-
- return appendTail(buffer).toString();
+ public boolean hitEnd() {
+ return NativeRegEx.hitEnd(nativePattern);
}
/**
- * Returns a replacement string for the given one that has all backslashes
- * and dollar signs escaped.
- *
- * @param s
- * the input string.
- * @return the input string, with all backslashes and dollar signs having
- * been escaped.
- * @since Android 1.0
+ * Sets a new pattern for the {@code Matcher}. Results of a previous find
+ * get lost. The next attempt to find an occurrence of the {@link Pattern}
+ * in the string will start at the beginning of the input.
+ *
+ * @param pattern
+ * the new {@code Pattern}.
+ *
+ * @return the {@code Matcher} itself.
*/
- public static String quoteReplacement(String s) {
- StringBuffer buffer = new StringBuffer(s.length());
-
- for (int i = 0; i < s.length(); i++) {
- char c = s.charAt(i);
- if (c == '\\' || c == '$') {
- buffer.append('\\');
- }
- buffer.append(c);
+ public Matcher usePattern(Pattern pattern) {
+ if (pattern == null) {
+ throw new IllegalArgumentException();
}
-
- return buffer.toString();
+
+ this.pattern = pattern;
+
+ if (nativePattern != 0) {
+ NativeRegEx.close(nativePattern);
+ }
+ nativePattern = NativeRegEx.clone(pattern.mNativePattern);
+
+ if (input != null) {
+ NativeRegEx.setText(nativePattern, input);
+ NativeRegEx.setRegion(nativePattern, regionStart, regionEnd);
+ NativeRegEx.useAnchoringBounds(nativePattern, anchoringBounds);
+ NativeRegEx.useTransparentBounds(nativePattern, transparentBounds);
+ }
+
+ matchOffsets = new int[(this.pattern.mGroupCount + 1) * 2];
+ matchFound = false;
+ return this;
}
@Override
diff --git a/regex/src/main/java/java/util/regex/Pattern.java b/regex/src/main/java/java/util/regex/Pattern.java
index 2c71de1..db3bc21 100644
--- a/regex/src/main/java/java/util/regex/Pattern.java
+++ b/regex/src/main/java/java/util/regex/Pattern.java
@@ -47,7 +47,7 @@ import com.ibm.icu4jni.regex.NativeRegEx;
* boolean b2 = Pattern.matches("Hello, A[a-z]*!", "Hello, Robot!"); // false
* </pre>
* <p/>
- * Please consult the <a href="package-summary.html">package documentation</a> for an
+ * Please consult the <a href="package.html">package documentation</a> for an
* overview of the regular expression syntax used in this class as well as
* Android-specific implementation details.
*
@@ -61,8 +61,6 @@ public final class Pattern implements Serializable {
/**
* This constant specifies that a pattern matches Unix line endings ('\n')
* only against the '.', '^', and '$' meta characters.
- *
- * @since Android 1.0
*/
public static final int UNIX_LINES = 0x01;
@@ -76,8 +74,6 @@ public final class Pattern implements Serializable {
* constant. So if case insensitivity is enabled, this automatically extends
* to all Unicode characters. The {@code UNICODE_CASE} constant itself has
* no special consequences.
- *
- * @since Android 1.0
*/
public static final int CASE_INSENSITIVE = 0x02;
@@ -85,8 +81,6 @@ public final class Pattern implements Serializable {
* This constant specifies that a {@code Pattern} may contain whitespace or
* comments. Otherwise comments and whitespace are taken as literal
* characters.
- *
- * @since Android 1.0
*/
public static final int COMMENTS = 0x04;
@@ -94,24 +88,18 @@ public final class Pattern implements Serializable {
* This constant specifies that the meta characters '^' and '$' match only
* the beginning and end end of an input line, respectively. Normally, they
* match the beginning and the end of the complete input.
- *
- * @since Android 1.0
*/
public static final int MULTILINE = 0x08;
/**
* This constant specifies that the whole {@code Pattern} is to be taken
* literally, that is, all meta characters lose their meanings.
- *
- * @since Android 1.0
*/
public static final int LITERAL = 0x10;
/**
* This constant specifies that the '.' meta character matches arbitrary
* characters, including line endings, which is normally not the case.
- *
- * @since Android 1.0
*/
public static final int DOTALL = 0x20;
@@ -126,8 +114,6 @@ public final class Pattern implements Serializable {
* constant. So if case insensitivity is enabled, this automatically extends
* to all Unicode characters. The {@code UNICODE_CASE} constant then has no
* special consequences.
- *
- * @since Android 1.0
*/
public static final int UNICODE_CASE = 0x40;
@@ -135,8 +121,6 @@ public final class Pattern implements Serializable {
* This constant specifies that a character in a {@code Pattern} and a
* character in the input string only match if they are canonically
* equivalent. It is (currently) not supported in Android.
- *
- * @since Android 1.0
*/
public static final int CANON_EQ = 0x80;
@@ -159,24 +143,144 @@ public final class Pattern implements Serializable {
* Holds the number of groups in the pattern.
*/
transient int mGroupCount;
-
+
+
/**
- * Compiles a regular expression, creating a new Pattern instance in the
- * process. This is actually a convenience method that calls {@link
- * #compile(String, int)} with a {@code flags} value of zero.
- *
- * @param pattern
- * the regular expression.
- *
- * @return the new {@code Pattern} instance.
- *
- * @throws PatternSyntaxException
- * if the regular expression is syntactically incorrect.
- *
- * @since Android 1.0
+ * Returns a {@link Matcher} for the {@code Pattern} and a given input. The
+ * {@code Matcher} can be used to match the {@code Pattern} against the
+ * whole input, find occurrences of the {@code Pattern} in the input, or
+ * replace parts of the input.
+ *
+ * @param input
+ * the input to process.
+ *
+ * @return the resulting {@code Matcher}.
*/
- public static Pattern compile(String pattern) throws PatternSyntaxException {
- return new Pattern(pattern, 0);
+ public Matcher matcher(CharSequence input) {
+ return new Matcher(this, input);
+ }
+
+ /**
+ * Splits the given input sequence at occurrences of this {@code Pattern}.
+ *
+ * <p>If this {@code Pattern} does not occur in the input, the result is an
+ * array containing the input (converted from a {@code CharSequence} to
+ * a {@code String}).
+ *
+ * <p>Otherwise, the {@code limit} parameter controls the contents of the
+ * returned array as described below.
+ *
+ * @param inputSeq
+ * the input sequence.
+ * @param limit
+ * Determines the maximum number of entries in the resulting
+ * array, and the treatment of trailing empty strings.
+ * <ul>
+ * <li>For n &gt; 0, the resulting array contains at most n
+ * entries. If this is fewer than the number of matches, the
+ * final entry will contain all remaining input.
+ * <li>For n &lt; 0, the length of the resulting array is
+ * exactly the number of occurrences of the {@code Pattern}
+ * plus one for the text after the final separator.
+ * All entries are included.
+ * <li>For n == 0, the result is as for n &lt; 0, except
+ * trailing empty strings will not be returned. (Note that
+ * the case where the input is itself an empty string is
+ * special, as described above, and the limit parameter does
+ * not apply there.)
+ * </ul>
+ *
+ * @return the resulting array.
+ */
+ public String[] split(CharSequence inputSeq, int limit) {
+ if (inputSeq.length() == 0) {
+ // Unlike Perl, which considers the result of splitting the empty
+ // string to be the empty array, Java returns an array containing
+ // the empty string.
+ return new String[] { "" };
+ }
+
+ int maxLength = limit <= 0 ? Integer.MAX_VALUE : limit;
+
+ String input = inputSeq.toString();
+ ArrayList<String> list = new ArrayList<String>();
+
+ Matcher matcher = new Matcher(this, inputSeq);
+ int savedPos = 0;
+
+ // Add text preceding each occurrence, if enough space.
+ while(matcher.find() && list.size() + 1 < maxLength) {
+ list.add(input.substring(savedPos, matcher.start()));
+ savedPos = matcher.end();
+ }
+
+ // Add trailing text if enough space.
+ if (list.size() < maxLength) {
+ if (savedPos < input.length()) {
+ list.add(input.substring(savedPos));
+ } else {
+ list.add("");
+ }
+ }
+
+ // Remove trailing empty matches in the limit == 0 case.
+ if (limit == 0) {
+ int i = list.size() - 1;
+ while (i >= 0 && "".equals(list.get(i))) {
+ list.remove(i);
+ i--;
+ }
+ }
+
+ return list.toArray(new String[list.size()]);
+ }
+
+ /**
+ * Splits a given input around occurrences of a regular expression. This is
+ * a convenience method that is equivalent to calling the method
+ * {@link #split(java.lang.CharSequence, int)} with a limit of 0.
+ *
+ * @param input
+ * the input sequence.
+ *
+ * @return the resulting array.
+ */
+ public String[] split(CharSequence input) {
+ return split(input, 0);
+ }
+
+ /**
+ * Returns the regular expression that was compiled into this
+ * {@code Pattern}.
+ *
+ * @return the regular expression.
+ */
+ public String pattern() {
+ return pattern;
+ }
+
+ @Override
+ public String toString() {
+ return pattern;
+ }
+
+ /**
+ * Returns the flags that have been set for this {@code Pattern}.
+ *
+ * @return the flags that have been set. A combination of the constants
+ * defined in this class.
+ *
+ * @see #CANON_EQ
+ * @see #CASE_INSENSITIVE
+ * @see #COMMENTS
+ * @see #DOTALL
+ * @see #LITERAL
+ * @see #MULTILINE
+ * @see #UNICODE_CASE
+ * @see #UNIX_LINES
+ */
+ public int flags() {
+ return flags;
}
/**
@@ -208,8 +312,6 @@ public final class Pattern implements Serializable {
* @see #MULTILINE
* @see #UNICODE_CASE
* @see #UNIX_LINES
- *
- * @since Android 1.0
*/
public static Pattern compile(String pattern, int flags) throws PatternSyntaxException {
return new Pattern(pattern, flags);
@@ -238,7 +340,24 @@ public final class Pattern implements Serializable {
compileImpl(pattern, flags);
}
-
+
+ /**
+ * Compiles a regular expression, creating a new Pattern instance in the
+ * process. This is actually a convenience method that calls {@link
+ * #compile(String, int)} with a {@code flags} value of zero.
+ *
+ * @param pattern
+ * the regular expression.
+ *
+ * @return the new {@code Pattern} instance.
+ *
+ * @throws PatternSyntaxException
+ * if the regular expression is syntactically incorrect.
+ */
+ public static Pattern compile(String pattern) {
+ return new Pattern(pattern, 0);
+ }
+
/**
* Compiles the given regular expression using the given flags. Used
* internally only.
@@ -266,56 +385,6 @@ public final class Pattern implements Serializable {
}
/**
- * Returns the regular expression that was compiled into this
- * {@code Pattern}.
- *
- * @return the regular expression.
- *
- * @since Android 1.0
- */
- public String pattern() {
- return pattern;
- }
-
- /**
- * Returns the flags that have been set for this {@code Pattern}.
- *
- * @return the flags that have been set. A combination of the constants
- * defined in this class.
- *
- * @see #CANON_EQ
- * @see #CASE_INSENSITIVE
- * @see #COMMENTS
- * @see #DOTALL
- * @see #LITERAL
- * @see #MULTILINE
- * @see #UNICODE_CASE
- * @see #UNIX_LINES
- *
- * @since Android 1.0
- */
- public int flags() {
- return flags;
- }
-
- /**
- * Returns a {@link Matcher} for the {@code Pattern} and a given input. The
- * {@code Matcher} can be used to match the {@code Pattern} against the
- * whole input, find occurrences of the {@code Pattern} in the input, or
- * replace parts of the input.
- *
- * @param input
- * the input to process.
- *
- * @return the resulting {@code Matcher}.
- *
- * @since Android 1.0
- */
- public Matcher matcher(CharSequence input) {
- return new Matcher(this, input);
- }
-
- /**
* Tries to match a given regular expression against a given input. This is
* actually nothing but a convenience method that compiles the regular
* expression into a {@code Pattern}, builds a {@link Matcher} for it, and
@@ -332,107 +401,12 @@ public final class Pattern implements Serializable {
*
* @see Pattern#compile(java.lang.String, int)
* @see Matcher#matches()
- *
- * @since Android 1.0
*/
- static public boolean matches(String regex, CharSequence input) {
+ public static boolean matches(String regex, CharSequence input) {
return new Matcher(new Pattern(regex, 0), input).matches();
}
/**
- * Splits a given input around occurrences of a regular expression. This is
- * a convenience method that is equivalent to calling the method
- * {@link #split(java.lang.CharSequence, int)} with a limit of 0.
- *
- * @param input
- * the input sequence.
- *
- * @return the resulting array.
- *
- * @since Android 1.0
- */
- public String[] split(CharSequence input) {
- return split(input, 0);
- }
-
- /**
- * Splits the given input sequence at occurrences of this {@code Pattern}.
- *
- * If this {@code Pattern} does not occur in the input, the result is an
- * array containing the input (converted from a {@code CharSequence} to
- * a {@code String}).
- *
- * Otherwise, the {@code limit} parameter controls the contents of the
- * returned array as described below.
- *
- * @param inputSeq
- * the input sequence.
- * @param limit
- * Determines the maximum number of entries in the resulting
- * array, and the treatment of trailing empty strings.
- * <ul>
- * <li>For n &gt; 0, the resulting array contains at most n
- * entries. If this is fewer than the number of matches, the
- * final entry will contain all remaining input.
- * <li>For n &lt; 0, the length of the resulting array is
- * exactly the number of occurrences of the {@code Pattern}
- * plus one for the text after the final separator.
- * All entries are included.
- * <li>For n == 0, the result is as for n &lt; 0, except
- * trailing empty strings will not be returned. (Note that
- * the case where the input is itself an empty string is
- * special, as described above, and the limit parameter does
- * not apply there.)
- * </ul>
- *
- * @return the resulting array.
- *
- * @since Android 1.0
- */
- public String[] split(CharSequence inputSeq, int limit) {
- if (inputSeq.length() == 0) {
- // Unlike Perl, which considers the result of splitting the empty
- // string to be the empty array, Java returns an array containing
- // the empty string.
- return new String[] { "" };
- }
-
- int maxLength = limit <= 0 ? Integer.MAX_VALUE : limit;
-
- String input = inputSeq.toString();
- ArrayList<String> list = new ArrayList<String>();
-
- Matcher matcher = new Matcher(this, inputSeq);
- int savedPos = 0;
-
- // Add text preceding each occurrence, if enough space.
- while(matcher.find() && list.size() + 1 < maxLength) {
- list.add(input.substring(savedPos, matcher.start()));
- savedPos = matcher.end();
- }
-
- // Add trailing text if enough space.
- if (list.size() < maxLength) {
- if (savedPos < input.length()) {
- list.add(input.substring(savedPos));
- } else {
- list.add("");
- }
- }
-
- // Remove trailing empty matches in the limit == 0 case.
- if (limit == 0) {
- int i = list.size() - 1;
- while (i >= 0 && "".equals(list.get(i))) {
- list.remove(i);
- i--;
- }
- }
-
- return list.toArray(new String[list.size()]);
- }
-
- /**
* Quotes a given string using "\Q" and "\E", so that all other
* meta-characters lose their special meaning. If the string is used for a
* {@code Pattern} afterwards, it can only be matched literally.
@@ -441,27 +415,20 @@ public final class Pattern implements Serializable {
* the string to quote.
*
* @return the quoted string.
- *
- * @since Android 1.0
*/
public static String quote(String s) {
- StringBuffer sb = new StringBuffer().append("\\Q");
+ StringBuilder sb = new StringBuilder().append("\\Q"); //$NON-NLS-1$
int apos = 0;
int k;
- while ((k = s.indexOf("\\E", apos)) >= 0) {
- sb.append(s.substring(apos, k + 2)).append("\\\\E\\Q");
+ while ((k = s.indexOf("\\E", apos)) >= 0) { //$NON-NLS-1$
+ sb.append(s.substring(apos, k + 2)).append("\\\\E\\Q"); //$NON-NLS-1$
apos = k + 2;
}
- return sb.append(s.substring(apos)).append("\\E").toString();
+ return sb.append(s.substring(apos)).append("\\E").toString(); //$NON-NLS-1$
}
@Override
- public String toString() {
- return pattern;
- }
-
- @Override
protected void finalize() throws Throwable {
try {
if (mNativePattern != 0) {
@@ -474,7 +441,7 @@ public final class Pattern implements Serializable {
}
/**
- * Provides serialization support
+ * Serialization support
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
diff --git a/regex/src/main/java/java/util/regex/PatternSyntaxException.java b/regex/src/main/java/java/util/regex/PatternSyntaxException.java
index e4d5abd..d59bdd4 100644
--- a/regex/src/main/java/java/util/regex/PatternSyntaxException.java
+++ b/regex/src/main/java/java/util/regex/PatternSyntaxException.java
@@ -1,17 +1,18 @@
/*
- * Copyright (C) 2007 The Android Open Source Project
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
*
- * 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
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * http://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.
+ * 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 java.util.regex;
@@ -25,24 +26,22 @@ import java.util.Arrays;
*
* @see Pattern#compile(String)
* @see Pattern#compile(java.lang.String,int)
- *
- * @since Android 1.0
*/
public class PatternSyntaxException extends IllegalArgumentException {
private static final long serialVersionUID = -3864639126226059218L;
-
- /**
- * Holds the syntactically incorrect regular expression, or null if the
- * regular expression is not known.
- */
- private String pattern;
/**
* Holds the description of the syntax error, or null if the description is
* not known.
*/
- private String description;
+ private String desc;
+
+ /**
+ * Holds the syntactically incorrect regular expression, or null if the
+ * regular expression is not known.
+ */
+ private String pattern;
/**
* Holds the index around which the error occured, or -1, in case it is
@@ -63,11 +62,10 @@ public class PatternSyntaxException extends IllegalArgumentException {
* @param index
* the character index around which the error occurred, or -1 if
* the index is not known.
- * @since Android 1.0
*/
public PatternSyntaxException(String description, String pattern, int index) {
+ this.desc = description;
this.pattern = pattern;
- this.description = description;
this.index = index;
}
@@ -76,7 +74,6 @@ public class PatternSyntaxException extends IllegalArgumentException {
*
* @return the regular expression.
*
- * @since Android 1.0
*/
public String getPattern() {
return pattern;
@@ -88,16 +85,15 @@ public class PatternSyntaxException extends IllegalArgumentException {
* original regular expression, and the index at which the error occured.
*
* @return the error message.
- *
- * @since Android 1.0
*/
@Override
public String getMessage() {
+ // BEGIN android-changed
StringBuilder builder = new StringBuilder("Syntax error");
- if (description != null) {
+ if (desc != null) {
builder.append(' ');
- builder.append(description);
+ builder.append(desc);
}
if (index >= 0) {
@@ -118,6 +114,7 @@ public class PatternSyntaxException extends IllegalArgumentException {
}
return builder.toString();
+ // END android-changed
}
/**
@@ -125,10 +122,9 @@ public class PatternSyntaxException extends IllegalArgumentException {
* description is not known.
*
* @return the description.
- * @since Android 1.0
*/
public String getDescription() {
- return description;
+ return desc;
}
/**
@@ -137,10 +133,8 @@ public class PatternSyntaxException extends IllegalArgumentException {
*
* @return the index.
*
- * @since Android 1.0
*/
public int getIndex() {
return index;
}
-
}