zxcv さんが書きました:
Perlの場合だと、空文字列が帰るならバグですね。
なぜかと言うと \d* の * は最長マッチと決められているからです。
JavaScriptの場合、標準でどう決められているか見付からなかったので自信が無かったのですが、最短マッチするか最長マッチするか予測困難では使えないですし、そもそもそんなのが標準にはならないはずですよね?
JavaScriptはPerlではない。
JavaScriptはECMAScriptをベースにしているので、ECMAScriptの仕様書に聞くしかない。
String.matchを見ると、String.match(...)において、... がRegExpオブジェクトでなかったら ... をRegExpオブジェクトに変換し、RegExp.exec()を呼ぶ、云々と書いてある。
そして、RegExp.global=falseで、zero or more occurrencesの時は、長さをゼロにしてRegExp.exec()を一回だけCallし、結果はゼロか正の無限大、となにやら怪しげなことが書いてある。
で、「JavaScriptのRegExpオブジェクト」を見ると、
Metacharacter \d Find a digit
Quantifier n* Matches any string that contains zero or more occurrences of n
Quantifier n+ Matches any string that contains at least one n
Modifier g Perform a global match (find all matches rather than stopping after the first match)
RegExp Object Property global Specifies if the "g" modifier is set
「zero or more occurrences」、「at least one」、および、「global match(対は、non-global matchになるのかな)」、「find all matches rather than stopping after the first match」だからその対は「stopping after the first match」、と定義されている。
Modifier gは、RegExp.globalに対応し、ここでECMAScriptの記述に遭遇。
ここには、最短マッチだの最長マッチだのとは、書かれてはいない。
ましてや、Quantifierの「*」には、最短だの最長だのといった意味合いに対応するものは一切含まれていない。
そういう類のものは、RegExp.globalに分離してある。
(この辺が、仕様書で「intentionally generic」と言っている部分の一つかな)
"\d*"は、「Find a digit」で「zero or more occurrences」で、"/g"が無いから、そのままではglobal=falseで、「stopping after the first match」になる。
「zero or more occurrences」の時にまだ一回もマッチしていないのに「First」 matchとはこれ如何、Firstは1からじゃないのかぃ、ってなチャチャは無し。
イギリスのFirst FloorとアメリカのFirst Floorの違い、ってなことになるのかも。
ま、単に、マニュアルをちゃんと読まないからそうなる、という話になるでしょう。
"/i"ならまだしも、Regular expressionの文字列の中に"/g"を入れるのはちょっと気色悪いから、
var Str=" ... " ; var RegExpForDigit= new RegExp("/\d*/" );
RegExpForDigit.global=false; var a=Str(RegExpForDigit);
RegExpForDigit.global=true; var b=Str(RegExpForDigit);
とでもしてみるといいでしょう。
なお、JavaScriptには拡張が入っているので、ECMAScriptとは異なるものも多々あります。
基本的なものはECMAScriptの厳密な規定にほぼ従っていますが、RegExpでも、少し拡張が入っていたと思います。
何も調べずに、Perlと違う、ECMAScriptと違う、MSと違う、などと言って、bugzilla.mozilla.orgにバグを開かないでくださいね。