Re: 文字列"0123456789"を"9876543210"に変換する方法
[Javascript] 文字列"0123456789"を"9876543210"に変換する方法 たまには呪文をとなえてみるか:仕事版/ウェブリブログ
逆にするならreverseの方が自然かなあ?(Javascriptの正規表現の話という前提を壊してしまいますが)
>>> "0123456789".split('').reverse().join('') "9876543210"
JavaScriptは文字列にreverseできないので一旦配列にしてから逆転・結合します。
splitに空の正規表現(または文字列)を渡すと一文字ずつに分解した配列を返してくれます。(無理やり正規表現の話にしてみた)
>>> "0123456789" "0123456789" >>> "0123456789".split('') ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] >>> "0123456789".split('').reverse() ["9", "8", "7", "6", "5", "4", "3", "2", "1", "0"] >>> "0123456789".split('').reverse().join('') "9876543210"
ところでPerlは
% perl -e 'print scalar reverse "0123456789"' 9876543210
と直接文字列をreverseできます。簡単ですね。
ちょっとはまったのが、reverseがリストコンテキストで呼ばれるとリストの逆転を行なうところ。
リストコンテキストだと("0123456789")というリストを逆転した("0123456789")というリストが返ってきてしまうので、scalar演算子でスカラーコンテキストで呼び出しています。一旦スカラー変数に突っ込むならscalarいらないけど。
% perl -e 'my $x = reverse "0123456789"; print $x' 9876543210
ちょっと試してみたんだけれど、やっぱりIEではfunction内部ではRegExp.$1が定義されていない模様。
このため、キャプチャした文字列を相手に何かという事はできないみたい。
a.replace(new RegExp("(\\d)","g"), function() { return String(Math.abs(parseInt(arguments[1]) - 9)); } );
でいいんじゃないかな。マッチした部分文字列はreplace-functionの引数として渡ってきます。ちなみに0番目はマッチした部分全体で、1番目以降がグループマッチした部分文字列です。
a.replace(new RegExp("(\\d)","g"), function($0, $1) { return String(Math.abs(parseInt($1) - 9)); } );
のように明示的に仮引数に代入してもいいです。(「仮引数に代入」って言い回し久しぶりに聞いたな・・・)
replace-function内のRegExp.$nは確かにIEで変な動きしますね。
/REGEXP/g(グローバルマッチ)の場合、全てのマッチが完了するまで更新されないんだと思います。