String.replace の第二引数には、置換後の文字列を返す、独自の関数を指定できることを知った。目的にもよるが、グルーピングを使うときは RegExp.exec を繰り返すよりも使いやすい。
ただし、置換関数に渡される引数が可変で、いくらか複雑なので注意が必要。
以下、ActionSript 3.0 での例。
var str:String = "aaaA bbbB cccC"; str = str.replace(/([a-z]+)([A-Z])/g, function():String { trace(arguments); return arguments[1].toUpperCase() + arguments[2].toLowerCase(); }); trace(str); =========================== aaaA,aaa,A,0,aaaA bbbB cccC bbbB,bbb,B,5,aaaA bbbB cccC cccC,ccc,C,10,aaaA bbbB cccC AAAa BBBb CCCc
global フラグが立っているので、3 箇所のマッチ全てに対して置換関数が実行される。
この場合の引数の各要素は、
- 第一引数
- ([a-z]+)([A-Z]) にマッチする文字列
- 第二引数
- ([a-z]+) にマッチする文字列
- 第三引数
- ([A-Z]) にマッチする文字列
- 第四引数
- ([a-z]+)([A-Z]) にマッチする文字列の位置
- 第五引数
- replace を実行する文字列
となる。
Ecma-262.pdf の 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. 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.