src/jdk/nashorn/internal/objects/NativeRegExp.java
Print this page
*** 521,555 ****
final RegExpResult match = Global.instance().getLastRegExpResult();
return match == null ? "" : match.getGroup(9);
}
private RegExpResult execInner(final String string) {
int start = getLastIndex();
! if (! regexp.isGlobal()) {
start = 0;
}
if (start < 0 || start > string.length()) {
setLastIndex(0);
return null;
}
final RegExpMatcher matcher = regexp.match(string);
if (matcher == null || !matcher.search(start)) {
setLastIndex(0);
return null;
}
! if (regexp.isGlobal()) {
setLastIndex(matcher.end());
}
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) {
--- 521,576 ----
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 (!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 (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,608 ****
*
* @param string String to match.
* @return True if a match is found.
*/
public Object test(final String string) {
! return exec(string) != null;
}
/**
* Searches and replaces the regular expression portion (match) with the
* replaced text instead. For the "replacement text" parameter, you can use
--- 619,629 ----
*
* @param string String to match.
* @return True if a match is found.
*/
public Object test(final String string) {
! 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,823 ****
* @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();
}
RegExpResult match;
! final int inputLength = input.length();
int lastLength = -1;
int lastLastIndex = 0;
! while ((match = regexp.execInner(input)) != null) {
! final int 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));
}
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 (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) {
matches.add("");
}
} else {
! matches.add(input.substring(lastLastIndex, inputLength));
}
}
return new NativeArray(matches.toArray());
}
--- 784,842 ----
* @param string String to match.
* @param limit Split limit.
* @return Array of substrings.
*/
Object split(final String string, final long limit) {
if (limit == 0L) {
return new NativeArray();
}
+ final List<Object> matches = new ArrayList<>();
+
RegExpResult match;
! final int inputLength = string.length();
int lastLength = -1;
+ int lastIndex = 0;
int lastLastIndex = 0;
! while ((match = execSplit(string, lastIndex)) != null) {
! lastIndex = match.getIndex() + match.length();
if (lastIndex > lastLastIndex) {
! 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();
if (matches.size() >= limit) {
break;
}
}
// bump the index to avoid infinite loop
! 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 == string.length()) {
! if (lastLength > 0 || execSplit("", 0) == null) {
matches.add("");
}
} else {
! matches.add(string.substring(lastLastIndex, inputLength));
}
}
return new NativeArray(matches.toArray());
}