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()); }