簡單的說:咱們與字符串接觸的頻率很是之高,正則表達式能夠極大的提升複雜文本分析的效率,快速匹配出複雜的字符串。javascript
直接量語法(字面量)java
var expression = /pattern/flags ; //pattern 是要匹配的字符串模式 //flags用來標記正則表達式的行爲: i 不區分大小寫;g 表示全局搜索 ;m 表示多行模式 var reg = /ab/i ,表示匹配 字符串 'ab' 不區分大小寫
調用RegExp
對象的構造函數正則表達式
//RegExp 是js中一個內置的對象,是正則表達式的縮寫 var expression = new RegExp(pattern,flags) //flags 和直接量語法一致 //pattern 能夠是字符串模式,也能夠是一個標準的正則表達式,後者必須省略 flags //能夠寫成var reg = new RegExp('ab','i') 或者var reg = new RegExp(/ab/i) //不能寫成 var reg = new RegExp(/ab/,'i')
在ES5
中規定:使用直接量必須像直接調用RegExp
構造函數同樣,每次都建立一個新的RegExp實例
,因此
上面2
種方式建立正則表達式,除了過程不同,效果是同樣的。express
RegExp
每一個實例都有以下屬性:global
:布爾值,表示實例是否設置了 g
標誌數組
ignoreCase
:布爾值,表示是否設置了 i
標誌ide
multiLine
:布爾值,表示是否設置了m
標誌函數
source
:返回建立RegExp
對象實例時指定的表達式純文本字符串。不包含後面的標誌測試
lastIndex
:整數,表示實例在接下來的一次搜索匹配項的開始位置
,默認從0
開始ui
RegExp.prototype.exec()prototype
exec()
方法爲指定的一段字符串執行搜索匹配操做,返回包含第一個匹配項
的數組,regexObj.exec(str)
,沒有匹配到則返回 null,返回的數組是Array的實例,並且
返回值還包含另外2個屬性:
index: 匹配到的字符位於原始字符串的基於0的索引值 和
input: 原始字符串`
var myRe = /ab*/g; var str = 'abbcdefabh'; var oo = myRe.exec(str) // oo ==> ["abb"] // oo.index ==> 0 // myRe.lastIndex ==> 0 // 從返回結果能夠看出來,即便咱們設置了全局的g,exec也不會一次性返回全部的匹配結果 // 由於其定義就是 返回包含`第一個匹配項`的數組,只要第一次匹配到,後面就不繼續執行 // 咱們再執行一次 oo = myRe.exec(str) // oo ==> ["ab"] // oo.index ==> 3 // myRe.lastIndex ==> 3 // 再次執行以後能夠看到 匹配項和一些屬性值都發生了變化,說明 此次並非從頭開始
官方說明:當正則表達式使用 "g
" 標誌時,能夠屢次執行 exec
方法來查找同一個字符串中的成功匹配。當你這樣作時,查找將從正則表達式的 lastIndex
屬性指定的位置開始(也就是說下次的查詢將在上次匹配成功後面開始匹配,並且會循環,在匹配不到的時候,會從頭開始
)。(test()
也會更新 lastIndex
屬性)。
不加"g
" 標誌的時候,每次都是從 0 開始,因此各類屬性也不會改變
exec()
方法還有一個重要的做用:匹配捕獲組
var str= "cat2,hat8" ; var reg=/c(at)/ ; console.info(reg.exec(str));//運行返回 ["cat2", "at"] 加了捕獲組的時候,結果會把捕獲組一塊兒返回,不加則沒有,支持多個捕獲組
注意
IE
的 javascript
在 lastIndex
設計上存在誤差,沒加g
的狀況下也會每次發生改變,慎用
RegExp.prototype.test()
接收一個字符串參數,regexObj.exec(str)
,匹配返回true
,不然false
RegExp.prototype.toString() ( RegExp.prototype.toLocaleString())
RegExp
對象覆蓋了 Object
對象的 toString()
方法,並無繼承 Object.prototype.toString()
。對於 RegExp
對象,toString
方法返回一個該正則表達式的字面量
。
myExp = new RegExp("a+b+c"); alert(myExp.toString()); // 顯示 "/a+b+c/" foo = new RegExp("bar", "g"); alert(foo.toString()); // 顯示 "/bar/g"
String
的應用match
一個在字符串中執行查找匹配的String
方法,它返回一個數組或者在未匹配到時返回null
。
var oo = '121212'.match(/1/g) oo //["1", "1", "1"] var oo = '121212'.match(/1/) oo //["1"]
replace
一個在字符串中執行查找匹配的String
方法,而且使用替換字符串替換掉匹配到的子字符串。
'121212'.replace(/1/g,',') //",2,2,2"
split
一個使用正則表達式或者一個固定字符串分隔一個字符串,並將分隔後的子字符串存儲到數組中的String
方法。
//以數字分割字符串 'a1b2c33d4'.split(/\d*/) //["a", "b", "c", "d", ""]
search
一個在字符串中測試匹配的String
方法,它返回匹配到的位置索引
,或者在失敗時返回-1。
//查找連續2個數字的位置 'a1b2c33d4'.search(/(\d){2}/) // 5
把一串數字字符串千分位方式(逗號)轉化成金額符號
分析要點:
金額的千分位是從右往左,每3
位加一個逗號,可是正則表達式裏面從右往左不是很方便,因此第一步要把數字顛倒過來,字符串並無直接的顛倒方法,數組有,Array.prototype.reverse.call([1,2,3,4])
==>[4, 3, 2, 1],字符串轉數組也是很方便的,String.prototype.split.call('1234','')
==> ["1", "2", "3", "4"]
再把顛倒的數組拼接成字符串 Array.prototype.join.call([4,3,2,1],'')
==> 4321
小數點後面的不須要處理,因此咱們要獲取 String.prototype.split.call('12345.678','.')[1]
==> 12345
由於咱們這裏已經反轉了,因此真正要轉化的數字在第二個
前面都是準備工做,如今須要用正則表達式處理字符串,匹配連續的3位數字分割成數組 \d{3} 表示連續3個數字 String.prototype.match.call('1234',/\d{3}/) ==> ["123"]
,這裏把後面的一位數字和2位數字直接忽略了,而且沒有全局匹配,因此咱們要補充一下。
String.prototype.match.call('1234567891',/\d{3}|\d{2}|\d{1}/g) //["123", "456", "789", "1"]
最後就把數組用逗號鏈接,在用小數點和以前的小數位加在一塊兒,再像第一步那樣反轉一下順序就能夠了。
例子代碼
function money_thousandth (str){ //先檢查是否是符合數字類型 if(isNaN(str)){ return '必須傳入數字或者數字字符串' } str = str.toString(); //反轉順序並分割小數點 var arr = str.split('').reverse().join('').split('.'); //全局優先匹配連續的3位數字,或者2位,或者1位 var reg = /\d{3}|\d{2}|\d{1}/g; //有小數點取第二位,沒有則取第一位 var thousand = arr[1] || arr[0] ; //分割數組 var result_arr = thousand.match(reg); //逗號拼接分割好的金額 var result_str = result_arr.join(","); //與小數點前面加起來 var result = arr[1] ? arr[0] + '.'+ result_str : result_str //返回顛倒的數字字符串 return result.split('').reverse().join('') } money_thousandth(1234567898.12) //"1,234,567,898.12" money_thousandth('1234567898.12') //"1,234,567,898.12"