一個案例
如何把一串整數(shù)轉(zhuǎn)換成千位分隔形式,例如10000000000,轉(zhuǎn)換成10,000,000,000。
在了解正則表達(dá)式之前,想要實現(xiàn)這個功能,無論代碼量還是燒腦程度,都很令人抓狂,但若是運用正則表達(dá)式來解決的話,兩三行代碼即可搞定!匹配、替換那些符合某種規(guī)則的字符串,恰恰是正則表達(dá)式的強項。
正則表達(dá)式
概念
正則表達(dá)式,又稱規(guī)則表達(dá)式。(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),計算機科學(xué)的一個概念。它不僅僅是Javascript獨有的東西,絕大多數(shù)主流操作系統(tǒng)、主流開發(fā)語言、無數(shù)的應(yīng)用軟件中,都可以看到正則表達(dá)式的優(yōu)美舞姿。正則表達(dá)式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規(guī)則字符串”,這個“規(guī)則字符串”用來表達(dá)對字符串的一種過濾邏輯。
特點
- 靈活性、邏輯性、功能性非常強
- 可以迅速地用極簡單的方式達(dá)到字符串的復(fù)雜控制。
- 對于剛接觸的人來說,比較晦澀難懂。
本文只是通過解決上述案例進(jìn)而討論Javascript所支持的正則表達(dá)式的部分常用且重要的方法,想查詢Javascript中正則表達(dá)式的全部強大功能,請點擊此處JavaScript RegExp 對象,查看W3school官方文檔。
梳理思路
要先明白的是,我們將要轉(zhuǎn)換成的數(shù)字格式是這樣:從個位往左數(shù)起,每三位前插入一個千位分隔符,
,即可以想象成我們要把每三位數(shù)字前面的那個空""
匹配出來,并替換成千位分隔符,
。每個千位分隔符后面的數(shù)字個數(shù)是3個或3的倍數(shù)個。
代碼書寫
創(chuàng)建一個正則表達(dá)式字面量,并加上全局匹配修飾符g。var reg = //g;
W3C對全局匹配的解釋是:查找所有匹配而非在找到第一個匹配后停止。
因為需要從右往左匹配,所以表示結(jié)尾的$
是必須要有的。三位數(shù)字用\d{3}
來表示,由于我們不知道究竟有多少組這樣的三位數(shù)字,所以需要在\d{3}
后面加上+
,來表示匹配任何包含至少一組三位數(shù)字的字符串。至目前,/(\d{3})+$/g
表示作為結(jié)尾的3個或3的倍數(shù)個數(shù)字。
由于要替換的是每三位數(shù)(從末尾起)緊前面的那個""
,所以需要用到正向預(yù)查,即?=n
(匹配任何其后緊接指定字符串 n 的字符串)。正向預(yù)查咋用呢?這里先舉個例子:有一個字符串var str = "abaaaaa";
,我們想把后面跟著字符b的字符a表示出來,于是正則表達(dá)式寫法:var reg = /a(?=b)/g;
,匹配的是后面緊跟著字符b
的字符a
,字符串str
中只有一個符合條件的a
,最后查看匹配結(jié)果為["a"]。這個例子的代碼如下:
var str = "abaaaaa",
reg = /a(?=b)/g;
console.log(str.match(reg));
粗略了解正向預(yù)查之后,回到原來的案例,我們可以寫成/(?=(\d{3})+$)/g;
,為什么(?=...)
前面什么也不寫呀?因為我們要找的是那些后面緊跟著三位數(shù)字的""
呀,空當(dāng)然什么都不用寫了。
我們來檢驗一下,是不是匹配出來三個""
?
var str = "10000000000",
reg = /(?=(\d{3})+$)/g;
console.log(str.match(reg));
結(jié)果如下,果然是三個""
。
下面我們對這三個空進(jìn)行替換:
var str = "10000000000",
reg = /(?=(\d{3})+$)/g;
console.log(str.replace(reg, ","));
結(jié)果如下,轉(zhuǎn)換成功。
但是,還沒完……
現(xiàn)在是十一位數(shù)字,如果再加一個0,湊夠十二位數(shù)呢,它可是3的倍數(shù),我們試驗一下:
var str = "100000000000",
reg = /(?=(\d{3})+$)/g;
console.log(str.replace(reg, ","));
結(jié)果變成了這樣:
這串?dāng)?shù)字最前面也被添加了一個
,
。這個原因就不解釋了,你們應(yīng)該明白為什么。那么怎么解決呢?我們對代碼進(jìn)行一下完善,在\d
前面加一個非單詞邊界\B
,用來表示所匹配的這個空后面不能是一個單詞邊界,這樣就可以把最前面的這個,
去掉了。最終的代碼如下
var str = "100000000000",
reg = /(?=(\B\d{3})+$)/g;
console.log(str.replace(reg, ","));
總結(jié)
綜上,”把一串整數(shù)轉(zhuǎn)換成千位分隔形式“這個案例就說完了。我再把這個案例用到的一些知識點梳理一下。
-
g
是表示全局匹配的修飾符,全局匹配指查找所有匹配而非在找到第一個匹配后停止。 -
$
是表示結(jié)尾的量詞,如n$
,匹配的是任何以n為結(jié)尾的字符串。 -
\d
是查找數(shù)字的元字符。 -
n{X}
是匹配包含 X 個 n 的序列的字符串的量詞。 -
n+
是匹配任何包含至少一個 n 的字符串的量詞。 -
?=n
正向預(yù)查,用于匹配任何其后緊接指定字符串 n 的字符串。 -
match()
String對象的方法,作用是找到一個或多個正則表達(dá)式的匹配。 -
replace()
String對象的方法,作用是替換與正則表達(dá)式匹配的子串。 -
\B
是表示匹配非單詞邊界的元字符,與其互為補集的元字符是\b
,表示匹配單詞邊界。
本文無法做到十分細(xì)致,如果看完還是一頭霧水的話,需要先從頭學(xué)一下正則表達(dá)式。
歡迎提出意見或建議,感謝你的閱讀!