「金額とか、カンマ区切りの数値をJSで。」のつづき。小数点も考えてみたんだけどね...。


## 前回の復習から。

3桁区切りでカンマつけたいよね。というときの正規表現を教わったのがコレ。

[金額とか、カンマ区切りの数値をJSで（正規表現を説明してもらった件）。](http://qiita.com/ariyo13/items/ab410a84c74b23099648)

```javascript
[該当する数値].toString().replace(/(\d)(?=(\d{3})+$)/g , '$1,');
```

ただ、コレって整数限定ですねー。っていうところで小数はどうだろう。ってモクモク考え続けたのがこのエントリーです。

## 正規表現にかぎらなかったらカンタンなんだよね。

ふつうに考えると、「小数点の前だけ置換したらえーやん」ってなります。

```javascript
var targetNum = '123456789.123456789';
var delimiter = '.'; // 小数点。
var splitedNum = targetNum.toString().split(delimiter); // 小数点で区切っておいて
// 区切った前のとこだけ置換。それ以外は後から付け足し。
var replacedNum = splitedNum[0].replace(/(\d)(?=(\d{3})+$)/g , '$1,') + delimiter + splitedNum[1];
```

ね。ふつーでしょ？

## 正規表現だとできないの？

となると、一応、コレでもできる。

```javascript
// 最初の$を(\.\d+)に変えた状態。「最後」を「小数点以下」に変えた感じ。
[該当する数値].toString().replace(/(\d)(?=(\d{3})+(\.\d+))/g , '$1,');
```

ただ、コレだと **小数値がある時限定** なのです。 **「整数だけのとき。小数点以下がない時。」にはマッチしない** のですよ...。

使う時には「整数だけ」でも「小数含んでる時」でも一緒に対応したいですよね。困った...。

## or条件だとできないの？

とか、くるかなぁと思うんですけどね。


```javascript
//「最後」か「小数点以下」でor条件にしたの。
[該当する数値].toString().replace(/(\d)(?=(\d{3})+($|\.\d+))/g , '$1,')

```

一見、よさそうなんですよ。ただですね...。

**小数点以下もカンマ区切りされちゃう！**

これは参った...。

これの回避をかなーり考えたのですが、

1. 小数点の前、というのを一旦切り分ける
2. 前に小数点がある、というのを認識する

のどちらかしか手がないのです。
正規表現的には1.はムリ。なので2.しかないんですけどね...。

## もういっかい、/(?=(hoge))/を考える。

んで、前回教えてもらった```/(?=(hoge))/```。

これ、「先読み」といわれるもので、```x(?=y)```の場合、 **'x' に 'y' が続く場合のみ 'x' にマッチします**。

つまり、前回のは「数字3つ」の前にある「数字１つ」をマッチさせていたわけで、 **さらにその前、というのは見つけられない** のですね。

むーん。お手上げ。

ムリクリ「点の後ろに続いている数字１つ以上」をマッチさせようと思ったんですけど、それだと「１つ以上」が無限扱いされて、繰り返し拾うことができない。

色々やっては見たんですけど、ちょっとムリでしたわ...。

ま、何がなんでも正規表現のみでやらねばならぬ！！という機会とか、まぁないでしょうし...。

## 諦めて、関数つくっておしまいー。

もぅめんどくさくなって「小数点以下が3桁までってわかってたら↑でいーんじゃないのー？金額表記とか、ふつう小数点以下2桁だしー。2桁ならカンマ出ないやんー。」とかぶっちゃけ思ったりしたんですが、正規表現できないなら、代替する関数でも作っておこうかなと。

整数か小数かを見分けて、それぞれの正規表現で対応してみます。

```javascript
function delimitNum(num){
	var delimiter = '.',
		numString = num.toString(),
		delimitExp = new RegExp('(\\d)(?=(\\d{3})+$)', 'g'), // 整数のときはこっちで置換。
		decimalDelimitExp = new RegExp('(\\d)(?=(\\d{3})+(\\.\\d+))', 'g'); // 小数のときはこっちで置換。
		
	function isDecimal() { // 整数か小数かをわけわけ。
		if(numString.indexOf(delimiter) > -1){
			return true;
		} else {
			return false;
		}
	}
	
	if(isDecimal()){  // 小数ですよ。って言われたら。
		return numString.replace(decimalDelimitExp, '$1,');
	} else { // 小数ですよ。って言われなかったら。
		return numString.replace(delimitExp, '$1,');
	}
}
```

先生〜。エスケープ文字がめんどくさいですー＞＜。とか、小数点の前だけ置換して戻したらええやん。って思う場合は、

```javascript
function delimitNum(num){
	var delimiter = '.',
    	numString = num.toString(), 
		targetNum; // 置き換える文字列の置き場所を決めておこうかなと。
      
	function isDecimal() { // 整数か小数かをわけわけ。
		if(numString.indexOf(delimiter) > -1){
			return true;
		} else {
			return false;
		}
	}
	
	if(isDecimal()){ // 小数だったら、前と後ろを分けておく。
		targetNum = numString.split(delimiter);
	} else { // 整数だったらそのまま。
		targetNum = numString;
	}
  
	if(targetNum instanceof Array){ // わけわけされてたら、前を置換して、小数点付けて後ろをまるっと付け足し。
    	return targetNum[0].replace(/(\d)(?=(\d{3})+$)/g , '$1,') + delimiter + targetNum[1];
	} else { // わけわけされてなかったら、そのまま置換。
		return targetNum.replace(/(\d)(?=(\d{3})+$)/g , '$1,')
	}
}
```

こんな感じですかねー...。私の頭だとこのくらいしか思い浮かばなかったです...。
正規表現得意な方、「こうすればー？」とかありましたらご助言おねがいしますーm(\_"\_)m


## 参考にさせていただきました。

[正規表現 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Regular_Expressions)