JavaScriptの動かないコード (中級編) splitで文字列を分割する時のエラー
以下のJavaScriptコードが意図した動作をしないのは,なぜですか。(制限時間1分)
やりたい事:
- 言葉の間に句読点の無い文章中に「。」をつけたい。
- お早う今日は今晩は今日はお早う。 → お早う。今日は。今晩は。今日は。お早う。
<script language="JavaScript"> // split() で文字列を分割する。 // パターン中で () でくくった部分は,マッチ結果の一部として, // 分割後の配列中に含まれる。 alert( "お早う今日は今晩は今日はお早う。" .split( /(今日は)/ ) .join("。") ); </script>
答え
Firefoxでは,意図した通り,
お早う。今日は。今晩は。今日は。お早う。
と表示される。しかしIEでは
お早う。今晩は。お早う。
となってしまう。
split() 中の括弧が,IEでは機能していない。
split() 中の正規表現で,「今日は」という文字列はセパレータとしての役割を持つ。
文字列はセパレータを区切りに分割され,分割結果は配列に格納される。
ECMA規格によれば,セパレータに ( ) を付けた場合,( ) 内の文字列もマッチ時に配列に格納されるべき。
ECMAScriptの仕様:
15.5.4.14 String.prototype.split (separator, limit)
http://www2u.biglobe.ne.jp/~oz-07ams/...separator が捕捉括弧を含む正規表現ならば、 separator が捕捉括弧の結果 (結果 undefined を含む) にマッチするごとに、出力配列内に継ぎ足される。 (例えば、 "A<B>bold</B>and<CODE>coded</CODE>".split(/<(\/)?([^<>]+)>/) は配列 ["A", undefined, "B", "bold", "/", "B", "and", undefined, "CODE", "coded", "/", "CODE", ""] に評価される。)
Firefoxはこの仕様通りだが,IEはそうではないらしい。
このブラウザ間の差異を吸収するためには,split時に ( ) でくくる方法を使うのを控えるのがよいだろう。
<script language="JavaScript"> // 分割時にセパレータを取り去ってから, // 結合時にセパレータを再度付加する。 alert( "お早う今日は今晩は今日はお早う。" .split( /今日は/ ) .join("。今日は。") ); </script>
正規表現中の ( ) は,複雑な指定をする際に本来ならばとても強力な武器になるのだが,この仕様の相違は残念だ。