切记:正则表达式匹配的是片段,是符合条件的某段字符串或几段字符串!
1、 给一个连字符串例如:get-element-by-id转化成驼峰形式。
var str = "get-element-by-id";
var reg = /-(\w)/g;
console.log(str.replace(reg, function(match, p1){
return p1.toString().toUpperCase();
})); //getElementById
字符串的转为大写:toUpperCase();转为小写:toLowerCase()
2、匹配一个[1-255]的数字
括号内匹配符合条件的值都可以,但是要以匹配的括号内容开头且结尾。这样就不会匹配345中的34和5了。
var str = "248";
var reg = /^([1]\d\d|[2][0-4]\d|[2]5[0-5]|[1-9]\d|[1-9])$/
console.log(str.match(reg));
3、匹配ip地址
var str = "248.89.31.26";
var reg = /^(([1]\d\d|[2][0-4]\d|[2]5[0-5]|[1-9]\d|[1-9])\.){3}([1]\d\d|[2][0-4]\d|[2]5[0-5]|[1-9]\d|[1-9])$/
console.log(str.match(reg));
打印结果:
4、关于开头和结尾
开头^和结尾$运算符 的优先级只大于 或 |
开头或结尾运算符修饰的是整个正则,除非有或
比如:匹配以多个数字和m开头的片段
var str = "12346m";
var reg = /^\d+m/g;
console.log(str.match(reg)); //["12346m"]
比如:匹配以多个数字和m结尾的片段
var str = "12346m";
var reg = /\d+m$/g;
console.log(str.match(reg)); //["12346m"]
再比如:匹配以多个数字和m开头,且以这个几个数字和这个m结尾!因为^$同时修饰的是匹配到的该片段!
var str = "12346m";
var reg = /^\d+m$/g;
console.log(str.match(reg)); //["12346m"]
如果有或|,匹配以多个数字开头的片段 或者 以m结尾的片段
var str = "12346m";
var reg = /^\d+|m$/g;
console.log(str.match(reg)); //["12346", "m"]
5、量词之间要用(),连着两个量词的正则表达式是错误的!
var reg = /\d{1,3}*/g
量词{1,3}后面再跟量词*将会报错!!!
6、子表达式嵌套子表达式,他们的先后顺序,谁是$1,谁又是$2
下面表达式reg1,(\d{1,3})是第一个子表达式;((\d{3})*)第二个子表达式;(\d{3})第三个子表达式。
特点:正则中,括号从左到右,从外到内
var str = "1234567890";
var reg1 = /^(\d{1,3})((\d{3})*)$/
var reg2 = /\d{3}/g
console.log(str.match(reg1))
var replaceStr = str.replace(reg1, function (match, p1, p2, p3) {
return p1 + p2.replace(reg2, ",$&")
})
console.log(replaceStr);
7、子表达式后面跟有量词,最后一次匹配到的内容,作为子表达式的值
我们知道非全局匹配下的match方法的结果和exec方法的结果一样,会得到所有的匹配信息,包括子表达式的内容。
以下例子中,子表达式的值是456,匹配多个3数字,最后一个3数字的内容。
var str = "12345678";
var reg = /(\d{3})*/
console.log(str.match(reg))
["123456", "456", index: 0, input: "12345678", groups: undefined]
8、| 或情况下的子表达式可能是undefined
在或 | 的情况下,有的子表达式未匹配到内容,其值是undefined。
结果会有第二个子表达式的值,但值是undefined。如果继续往后面匹配,比如用exec多次执行往后匹配,当匹配b1的时候,第一个子表达式是undefined,而第二个子表达式是b1。
var str = "a1b1a2b2";
var reg = /(a\d)|(b\d)/
console.log(str.match(reg))
["a1", "a1", undefined, index: 0, input: "a1b1a2b2", groups: undefined]
9、如何让正则表达式匹配先匹配后面的片段,再匹配前面的片段
我们知道正则表达式是从字符串的前面开始匹配,即从左到右进行匹配寻找符合条件的片段,比如:
下面字符串“12345”,匹配连续的两个数字,会匹配到12 和 34;而不是 23 和45
var str = "12345";
var reg = /\d{2}/g
console.log(str.match(reg)); //["12", "34"]
如果就是想匹配23和45呢?我们必须使用$符,因为我们无法从右往左匹配,只能先把2345匹配出来,再进行匹配拆分:
var str = "12345";
var reg1 = /(\d{2})+$/g
var reg2 = /\d{2}/g;
console.log(str.match(reg1)[0].match(reg2)) // ["23", "45"]
10、关于$符,结尾的作用时的匹配匹配规则
没有$符时,\d{1,3}会先匹配三个数字,(\d{3})*再匹配三个数字。然后\d{1,3}再匹配剩下的78
var str = "12345678";
var reg = /\d{1,3}(\d{3})*/g
console.log(str.match(reg)) // ["123456", "78"]
如果非全局匹配:也先匹配3个数字
var str = "12345678";
var reg = /\d{1,3}(\d{3})*/
console.log(str.match(reg))
// ["123456", "456", index: 0, input: "12345678", groups: undefined]
如果有开头符号,也是先匹配3个数字
var str = "12345678";
var reg = /^\d{1,3}(\d{3})*/g
console.log(str.match(reg)) // ["123456"]
我们再来看看有$符时,\d{1,3}就会优先让(\d{3})*先匹配符合的数字,剩下的再由\d{1,3}匹配,这样\d{1,3}就不会先匹配了。
var str = "12345678";
var reg = /\d{1,3}(\d{3})*$/g
console.log(str.match(reg)) // ["12345678"]
匹配结果:["12345678"],345和678是(\d{3})*匹配到的,12是\d{1,3}匹配到的。
如果同时有开头符^和结束符$:还是先倒着匹配,即先看 (\d{3})* 再看\d{1,3}。这就是$符的特性
var str = "12345678";
var reg = /^\d{1,3}(\d{3})*$/g
console.log(str.match(reg)) //["12345678"]
11、重点例题
给一串数字添加千位分号
比如:
1234567 ——》 1,234,567
12 ——》 12
123456 ——》 123,456
实现:通过reg1的$符的特性和^$符锁定,得到两部分,第一部分是前面剩余的数字,第二部分是后面长度为3的倍数部分。
当执行replace方法时,通过子表达式得到第二部分的内容,在用新的正则reg2添加逗号,从而实现
var str = "1234567890";
var reg1 = /^(\d{1,3})((\d{3})*)$/
var reg2 = /\d{3}/g
console.log(str.match(reg1))
var replaceStr = str.replace(reg1, function (match, p1, p2, p3) {
return p1 + p2.replace(reg2, ",$&")
})
console.log(replaceStr);