スポンサーリンク

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>


正規表現中の ( ) は,複雑な指定をする際に本来ならばとても強力な武器になるのだが,この仕様の相違は残念だ。