Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript String Replace with regular expression and function as arguments

I seem to be getting conflicting advice in the books I read on this functionality. I'm wondering if someone could clarify. For example Nicholas Zakas states the function argument has a signature of the format function(match, pos, originalText) (P139 : Pro JavaScript for Web Developers 2nd ed : Wrox)

He goes on to say When the regular expression has one match, the function gets passed three arguments (as above). When there are multiple capture groups, each matched string is passed in as an argument, with the last two positions being the position and originalText...

Then we come to Doug Crockfords, JavaScript: The Good Parts. (P90): He stipulates the syntax again as string(searcValue,replaceValue) searchValue can be a regex - great a match.. if replaceValue is a function, the first parameter is the matched text, then second is capture group 1, the third is capture group 2 and so on.. There is a noticeable difference here. (ie. No position argument)

I was also looking at an example in Pro JavaScript Design patterns (APress P152) that started this whole cross referencing process off. These guys (Ross Harmes/Dustin Diaz), rather unhelpfully specify the replaceValue function with two arguments named a & b. But it tends to reinforce the notion Doug Crockford describes.

Can someone confirm whether the Nicholas Zakas description is indeed a valid option too?

like image 539
JGFMK Avatar asked Nov 06 '10 16:11

JGFMK


2 Answers

Zakas is correct, the penultimate and final arguments are pos and originalText. From the ECMA-262 3rd and 5th editions (section 15.5.4.11):

If replaceValue is a function, then for each matched substring, call the function with the following m + 3 arguments. Argument 1 is the substring that matched. If searchValue is a regular expression, the next m arguments are all of the captures in the MatchResult (see 15.10.2.1). Argument m + 2 is the offset within string where the match occurred, and argument m + 3 is string.

Note that String.prototype.replace was new in ECMA-262 3rd edition. MSDN documentation for JScript and MDC documentation for JavaScript both conform to this specification.

  • replace Method (Windows Scripting - JScript)
  • replace - MDC
like image 150
Andy E Avatar answered Oct 05 '22 05:10

Andy E


The ECMAScript spec has:

String.prototype.replace (searchValue, replaceValue)

If searchValue is a regular expression (an object whose [[Class]] property is "RegExp"), do the following: If searchValue. global is false, then search string for the first match of the regular expression searchValue. If searchValue.global is true, then search string for all matches of the regular expression searchValue. Do the search in the same manner as in String.prototype.match, including the update of searchValue. lastIndex. Let m be the number of left capturing parentheses in searchValue (NCapturingParens as specified in 15.10.2.1).

If searchValue is not a regular expression, let searchString be ToString(searchValue) and search string for the first occurrence of searchString. Let m be 0.

If replaceValue is a function, then for each matched substring, call the function with the following m + 3 arguments. Argument 1 is the substring that matched. If searchValue is a regular expression, the next m arguments are all of the captures in the MatchResult (see 15.10.2.1). Argument m + 2 is the offset within string where the match occurred, and argument m + 3 is string. The result is a string value derived from the original input by replacing each matched substring with the corresponding return value of the function call, converted to a string if need be.

It's a bit confusing but I think Zakas is right.

like image 22
meder omuraliev Avatar answered Oct 05 '22 07:10

meder omuraliev