- 更新日: 2015年5月2日
- jQuery & JavaScript
JavaScriptでキャメルケースを単語に分割
JavaScript でキャメルケースの変数名やメソッド名の文字列を、区切りの単語ごとに分割したい機会がありました。例えば、”RequestUpdateCheckStatus” という文字列を “Request”, “Update”, “Check”, “Status” の4つの単語に分割して、以下のように配列として取得したい。
“RequestUpdateCheckStatus” → [ “Request”, “Update”, “Check”, “Status” ]
— 環境 —
Firefox 37.0.2
Google Chrome 42.0
JavaScript の正規表現では戻り読み(後読み)が使えない
すぐに思いついたのは、「小文字 + 大文字」の間で文字列を split する方法で、これには正規表現の先読みと戻り読み(後読み)を使うと簡単にできるはずと考えたのですが、コンソールで試してみたところ…
1 2 3 4 |
"RequestUpdateCheckStatus".split(/(?<=[a-z])(?=[A-Z])/); => SyntaxError: invalid regexp group |
これは、JavaScript の正規表現では戻り読み(後読み)がサポートされていないらしく、(?<=[a-z]) がエラーになるため。
正規表現の先読み・戻り読みが使える言語であれば、それを使うのがもっとも簡単だと思います。キャメルケースの単語分割で、正規表現の先読みと戻り読みを使う方法は以下参照。
キャメルケースを単語に分割する – うなの日記
JavaでCamelCaseを分割する – 勉強日記
正規表現のキャプチャ用括弧()を使って解決
JavaScript の String.prototype.split() で、正規表現の指定に括弧() を使うと、() にマッチした結果が戻り値の配列に含まれる。この機能を使って解決しました。
separator がキャプチャする括弧を含む場合、マッチした結果が戻り値の配列に含まれます。var myString = “Hello 1 word. Sentence number 2.”;
var splits = myString.split(/(\d)/);console.log(splits);
このスクリプトは、以下を表示します。
Hello , 1, word. Sentence number , 2, .
以下のように実装しました。
1 2 3 4 5 6 7 8 |
function isNotEmptyItem(element) { if ( element === "" || element === undefined ) { return false; } return true; } "RequestUpdateCheckStatus".split(/(^[a-z]+)|([A-Z][a-z]+)/).filter( isNotEmptyItem ); // => Array [ "Request", "Update", "Check", "Status" ] |
正規表現の前半 (^[a-z]+) は、lower camelcase(ローワーキャメルケース: 先頭文字が小文字のキャメルケース)に対応するため。
後半の ([A-Z][a-z]+) は、Request, Update などの「1文字目大文字 + 連続する小文字」にマッチさせる目的です。この後半部分で、upper camelcase(アッパーキャメルケース: 先頭文字が大文字のキャメルケース)にも対応できます。また fetchDataFromIDBStore のような途中に大文字のみ(IDB)の単語が含まれる文字列にも対応できる。
それから、isNotEmptyItem 関数で filter しているのは、空文字と undefined の配列要素を削除するためです。filter( isNotEmptyItem ) を書かないと、戻り値の配列に空文字と undefined が含まれます。
Array.prototype.filter() – JavaScript | MDN
実装にあたって、Python の例ですが以下の記事が参考になりました。
Pythonでキャメルケースの文字列を単語ごとに分割 – Qiita
Firefox, Chrome のコンソールで動作確認
最後に正しく動作するかを確認するために、Firefox と Chrome のデベロッパーツールのコンソールで動作確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
function isNotEmptyItem(element) { if ( element === "" || element === undefined ) { return false; } return true; } => undefined "RequestUpdateCheckStatus".split(/(^[a-z]+)|([A-Z][a-z]+)/).filter( isNotEmptyItem ); => Array [ "Request", "Update", "Check", "Status" ] "getPackageDirectoryEntry".split(/(^[a-z]+)|([A-Z][a-z]+)/).filter( isNotEmptyItem ); => Array [ "get", "Package", "Directory", "Entry" ] "IDBVersionChangeEvent".split(/(^[a-z]+)|([A-Z][a-z]+)/).filter( isNotEmptyItem ); => Array [ "IDB", "Version", "Change", "Event" ] "fetchDataFromIDBStore".split(/(^[a-z]+)|([A-Z][a-z]+)/).filter( isNotEmptyItem ); => Array [ "fetch", "Data", "From", "IDB", "Store" ] |
正しく動作しているようです。アッパーキャメルケース/ローワーキャメルケースのほか、IDBVersionChangeEvent, fetchDataFromIDBStore のように、キャメルケースの一部に大文字のみの単語(IDB の部分)を含む場合にも対応できています。
- jQuery & JavaScript の関連記事
- React.js用にESLintをインストールして設定、JavaScriptコードを楽に検証しよう
- JavaScriptでHTMLコメント要素を取得する
- YahooのJavaScriptマップAPI(YOLP)で地図を描画
- HTML5のGeolocation APIで現在地の位置情報(緯度/経度)を取得するJavaScriptコード
- Browserify + GulpでクライアントのJavaScript / CoffeeScriptでrequire
- JavaScript/jQueryでDOM要素が存在するか確認する方法
- JavaScriptでスクロールを一時的に止める
- JavaScriptでcapitalize、アルファベット一文字目を大文字にする
- JavaScriptでrangeオブジェクトから座標を取得するコード
- CoffeeScript入門、クラス継承とメソッドのオーバーライド
Leave Your Message!