简单的说:咱们与字符串接触的频率很是之高,正则表达式能够极大的提升复杂文本分析的效率,快速匹配出复杂的字符串。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"