src/jdk/nashorn/internal/objects/NativeRegExp.java
Print this page
@@ -521,35 +521,56 @@
final RegExpResult match = Global.instance().getLastRegExpResult();
return match == null ? "" : match.getGroup(9);
}
private RegExpResult execInner(final String string) {
+ final boolean isGlobal = regexp.isGlobal();
int start = getLastIndex();
- if (! regexp.isGlobal()) {
+ if (!isGlobal) {
start = 0;
}
if (start < 0 || start > string.length()) {
+ if (isGlobal) {
setLastIndex(0);
+ }
return null;
}
final RegExpMatcher matcher = regexp.match(string);
if (matcher == null || !matcher.search(start)) {
+ if (isGlobal) {
setLastIndex(0);
+ }
return null;
}
- if (regexp.isGlobal()) {
+ if (isGlobal) {
setLastIndex(matcher.end());
}
final RegExpResult match = new RegExpResult(string, matcher.start(), groups(matcher));
globalObject.setLastRegExpResult(match);
return match;
}
+ // String.prototype.split method ignores the global flag and should not update lastIndex property.
+ private RegExpResult execSplit(final String string, int start) {
+ if (start < 0 || start > string.length()) {
+ return null;
+ }
+
+ final RegExpMatcher matcher = regexp.match(string);
+ if (matcher == null || !matcher.search(start)) {
+ return null;
+ }
+
+ final RegExpResult match = new RegExpResult(string, matcher.start(), groups(matcher));
+ globalObject.setLastRegExpResult(match);
+ return match;
+ }
+
/**
* Convert java.util.regex.Matcher groups to JavaScript groups.
* That is, replace null and groups that didn't match with undefined.
*/
private Object[] groups(final RegExpMatcher matcher) {
@@ -598,11 +619,11 @@
*
* @param string String to match.
* @return True if a match is found.
*/
public Object test(final String string) {
- return exec(string) != null;
+ return execInner(string) != null;
}
/**
* Searches and replaces the regular expression portion (match) with the
* replaced text instead. For the "replacement text" parameter, you can use
@@ -763,61 +784,59 @@
* @param string String to match.
* @param limit Split limit.
* @return Array of substrings.
*/
Object split(final String string, final long limit) {
- return split(this, string, limit);
- }
-
- private static Object split(final NativeRegExp regexp0, final String input, final long limit) {
- final List<Object> matches = new ArrayList<>();
-
- final NativeRegExp regexp = new NativeRegExp(regexp0);
- regexp.setGlobal(true);
-
if (limit == 0L) {
return new NativeArray();
}
+ final List<Object> matches = new ArrayList<>();
+
RegExpResult match;
- final int inputLength = input.length();
+ final int inputLength = string.length();
int lastLength = -1;
+ int lastIndex = 0;
int lastLastIndex = 0;
- while ((match = regexp.execInner(input)) != null) {
- final int lastIndex = match.getIndex() + match.length();
+ while ((match = execSplit(string, lastIndex)) != null) {
+ lastIndex = match.getIndex() + match.length();
if (lastIndex > lastLastIndex) {
- matches.add(input.substring(lastLastIndex, match.getIndex()));
- if (match.getGroups().length > 1 && match.getIndex() < inputLength) {
- matches.addAll(Arrays.asList(match.getGroups()).subList(1, match.getGroups().length));
+ matches.add(string.substring(lastLastIndex, match.getIndex()));
+ final Object[] groups = match.getGroups();
+ if (groups.length > 1 && match.getIndex() < inputLength) {
+ for (int index = 1; index < groups.length && matches.size() < limit; index++) {
+ matches.add(groups[index]);
+ }
}
lastLength = match.length();
- lastLastIndex = lastIndex;
if (matches.size() >= limit) {
break;
}
}
// bump the index to avoid infinite loop
- if (regexp.getLastIndex() == match.getIndex()) {
- regexp.setLastIndex(match.getIndex() + 1);
+ if (lastIndex == lastLastIndex) {
+ lastIndex++;
+ } else {
+ lastLastIndex = lastIndex;
}
}
if (matches.size() < limit) {
// check special case if we need to append an empty string at the
// end of the match
// if the lastIndex was the entire string
- if (lastLastIndex == input.length()) {
- if (lastLength > 0 || regexp.test("") == Boolean.FALSE) {
+ if (lastLastIndex == string.length()) {
+ if (lastLength > 0 || execSplit("", 0) == null) {
matches.add("");
}
} else {
- matches.add(input.substring(lastLastIndex, inputLength));
+ matches.add(string.substring(lastLastIndex, inputLength));
}
}
return new NativeArray(matches.toArray());
}