Index: src/string.js |
=================================================================== |
--- src/string.js (revision 927) |
+++ src/string.js (working copy) |
@@ -198,9 +198,9 @@ |
if (start < 0) return subject; |
var end = start + search.length; |
- var builder = new StringBuilder(); |
+ var builder = new ReplaceResultBuilder(subject); |
// prefix |
- builder.add(SubString(subject, 0, start)); |
+ builder.addSpecialSlice(0, start); |
// Compute the string to replace with. |
if (IS_FUNCTION(replace)) { |
@@ -210,7 +210,7 @@ |
} |
// suffix |
- builder.add(SubString(subject, end, subject.length)); |
+ builder.addSpecialSlice(end, subject.length); |
return builder.generate(); |
} |
@@ -234,18 +234,27 @@ |
var length = matches.length; |
// Build the resulting string of subject slices and replacements. |
- var result = new StringBuilder(); |
+ var result = new ReplaceResultBuilder(subject); |
var previous = 0; |
// The caller of StringReplaceRegExp must ensure that replace is not a |
// function. |
replace = ToString(replace); |
- for (var i = 0; i < length; i++) { |
- var captures = matches[i]; |
- result.add(SubString(subject, previous, captures[0])); |
- ExpandReplacement(replace, subject, captures, result); |
- previous = captures[1]; // continue after match |
+ if (%StringIndexOf(replace, "$", 0) < 0) { |
+ for (var i = 0; i < length; i++) { |
+ var captures = matches[i]; |
+ result.addSpecialSlice(previous, captures[0]); |
+ result.add(replace); |
+ previous = captures[1]; // continue after match |
+ } |
+ } else { |
+ for (var i = 0; i < length; i++) { |
+ var captures = matches[i]; |
+ result.addSpecialSlice(previous, captures[0]); |
+ ExpandReplacement(replace, subject, captures, result); |
+ previous = captures[1]; // continue after match |
+ } |
} |
- result.add(SubString(subject, previous, subject.length)); |
+ result.addSpecialSlice(previous, subject.length); |
return result.generate(); |
}; |
@@ -272,15 +281,16 @@ |
var peek = %StringCharCodeAt(string, position); |
if (peek == 36) { // $$ |
++position; |
+ builder.add('$'); |
} else if (peek == 38) { // $& - match |
++position; |
- expansion = SubString(subject, captures[0], captures[1]); |
+ builder.addSpecialSlice(captures[0], captures[1]); |
} else if (peek == 96) { // $` - prefix |
++position; |
- expansion = SubString(subject, 0, captures[0]); |
+ builder.addSpecialSlice(0, captures[0]); |
} else if (peek == 39) { // $' - suffix |
++position; |
- expansion = SubString(subject, captures[1], subject.length); |
+ builder.addSpecialSlice(captures[1], subject.length); |
} else if (peek >= 48 && peek <= 57) { // $n, 0 <= n <= 9 |
++position; |
var n = peek - 48; |
@@ -301,20 +311,21 @@ |
} |
} |
if (0 < n && n < m) { |
- expansion = CaptureString(subject, captures, n); |
- if (IS_UNDEFINED(expansion)) expansion = ""; |
+ addCaptureString(builder, captures, n); |
} else { |
// Because of the captures range check in the parsing of two |
// digit capture references, we can only enter here when a |
// single digit capture reference is outside the range of |
// captures. |
+ builder.add('$'); |
--position; |
} |
} |
+ } else { |
+ builder.add('$'); |
} |
- // Append the $ expansion and go the the next $ in the string. |
- builder.add(expansion); |
+ // Go the the next $ in the string. |
next = %StringIndexOf(string, '$', position); |
// Return if there are no more $ characters in the string. If we |
@@ -345,6 +356,19 @@ |
}; |
+// Add the string of a given PCRE capture to the ReplaceResultBuilder |
+function addCaptureString(builder, captures, index) { |
+ // Scale the index. |
+ var scaled = index << 1; |
+ // Compute start and end. |
+ var start = captures[scaled]; |
+ var end = captures[scaled + 1]; |
+ // If either start or end is missing return. |
+ if (start < 0 || end < 0) return; |
+ builder.addSpecialSlice(start, end); |
+}; |
+ |
+ |
// Helper function for replacing regular expressions with the result of a |
// function application in String.prototype.replace. The function application |
// must be interleaved with the regexp matching (contrary to ECMA-262 |