正则表达式
面试中比较少问,问就是以笔试形式来问
在项目中会经常用,比如:校验与内容替换
正则表达式的构成
正则表达式可以由简单的字符组成,也可以是简单字符和特殊字符组成。其中特殊字符我们称为元字符,如:^ $ + 等等
/^[1-9]\d*$/
/^([1-9]\d*(\.\d{1,2})?|([0](\.([0][1-9]|[1-9]\d{0,1}))))$/
正则表达式中的特殊字符
字符类(匹配的是字符而不是类型)
字符 | 说明 |
---|---|
\d | 匹配任何数字(阿拉伯数字),相当于[0-9] |
\D | 匹配任何非数字(阿拉伯数字)的字符 |
\w | 匹配基本拉丁字母中的任何字母数字字符,包括下划线。相当于 [A-Za-z0-9_] |
\W | 匹配任何不是来自基本拉丁字母的单词字符 |
\s | 匹配单个空白字符包括空格 制表符 回车符 换行符,相当于[\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] |
\b | 匹配一个词的边界 |
边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
边界符 | 说明 |
---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
如果表达式中没有边界符,就是表示匹配字段中是否包含的关系
var rg = /123/ // 表示是否包含123这个字段
console.log(rg.test('1234'))// true
console.log(rg.test(1234))// true
用正则表达式的方法:test(匹配字段)来判断是否匹配,返回结果是布尔型
var rg = /\d/
console.log(rg.test(1))// true
// 创建正则的两种方式
// 1.字面量的方式创建
// 2.通过RegExpvar rg = /123/ // 字面量不用加引号
var rg = new RegExp(123)
// /123/ 匹配内容是否包含有123
var rg = /123/
console.log(rg.test('123'))
console.log(rg.test('1234'))
console.log(rg.test('41234'))
console.log('-----------------------')
// 匹配以123开头内容
var rg1 = /^123/
console.log(rg1.test('123'))// true
console.log(rg1.test('1234'))// true
console.log(rg1.test('41234'))// false
console.log('-----------------------')
// 精确匹配 要求内容必须是123
var rg2 = /^123$/
console.log(rg2.test('123'))// true
console.log(rg2.test('1234'))// false
console.log(rg2.test('41234'))// false
console.log(rg2.test('123123'))// false
^和$一起使用表示精确匹配
字符集合
字符集合表示有一系列字符可供选择,只要匹配其中一个就可以。所有可供选择的字符都在方括号内
要匹配的字段中只要有其中一个就返回true
// 不带边界符
var rg = /[abc]/
rg.test('a') // true
rg.test('ab') // true
rg.test('abc') // true
rg.test('abcd') // true
// 存在起止边界符
//表示只能匹配abc中任意一种
var rg1 = /^[abc]$/
rg.test('a') // true
rg.test('ab') // false
rg.test('abc') // false
rg.test('abcd') // false
// 其他场景
var rg2 = /[a-z]/ // -表示取某个范围值
var rg3 = /[^a-z]/ // ^在中括号内表示取反
// 表示取非小写的a到z的值
量词符
紧跟着的是前面一个字符或分组
量词符用来设定某个模式出现的次数
量词符 | 说明 |
---|---|
* | 重复零次或更多次(大于等于0) |
+ | 重复一次或更多次(大于等于1) |
? | 重复零次或一次(0或1) |
{n} | 重复n次 |
{n, m} | 重复n到m次 |
// 匹配小写a到z的任意一个,加上不定个数的0
var rg = /^[a-z]0*$/
console.log(rg.test('a0'))// true
console.log(rg.test('az00'))// false// 匹配小写a到z的任意一个,加上一个或多个0
var rg1 = /^[a-z]0+$/
var rg2 = /^[a-z]0?$/
var rg3 = /^[a-z]0{2}$/
var rg4 = /^[a-z]0{1,2}$/
分组符号
对字符进行分组,小括号包裹的内容可以看作一个整体
// 以ab开头,c结尾且c能出现1或3次
var rg = /^abc{1,3}$/
// abc这个组合只能重复1或3次
var rg1 = /^(abc){1,3}$/
正则表达式的参数
思考一个问题
我们需要匹配到某个字符串中所有满足条件的字符,应该如何匹配?
var str = 'abcdacd'
var rg = /a/ // 匹配a
str.match(rg)
- 通过字符串调用match,match的参数是正则
- 如果能匹配到,返回一个匹配到的数组;匹配不到,就返回null
- 上述返回结果是[‘a’, index: 0, input: ‘abcdacd’, groups: undefined],展开后可以看到length:1,说明只能匹配一个a
实际上这个字符串中有两个a,所以想要全匹配到,就要添加一些参数
正则表达式参数
/表达式/[switch]
表示 | 说明 |
---|---|
g | 全局搜索 |
i | 不区分大小写搜索 |
m | 多行搜索 |
s | 允许.匹配换行符 |
u | 使用unicode码的模式进行匹配 |
y | 执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始 |
var str1 = 'abcdacd'
var rg = /a/g
str1.match(rg)// ['a','a']
添加一个g(global)就可以在全局匹配a,同时这些字符可以组合使用
var str2 = 'Aabcdacd'
var rg = /a/gi
str2.match(rg)// ['A',a','a']
i表示部分大小写搜索
正则表达式常见的用法
replace替换
replace方法可以实现替换字符串操作
// str.replace(regexp|substr, newSubStr|function)
// 第一个参数可以是正则或者字符串
// 第二个参数为需要替换的字符串或者一个函数,在函数中通过返回值来替换匹配到的内容
// 要求1:将手机号的中间四位替换成*,例如13877283312变成138****3312
var str1 = '13877283312'
var rg = /(\d{3})(\d{4})(\d{4})/
str1.replace(rg,'$1****$3')// 138****3312
- 要求1中,对手机号中间4位替换为4个星号,我们选择用正则的方式替换,所以要写一个正则来匹配这个电话号,于是对电话号进行分组,前3为一组,后面的以4个为一组
- 通过字符串调用replace来替换,第二个参数是我们要替换的内容,在replace中,可以使用变量来进行替换,但是前提是第一个参数必须是正则表达式,同时变量是正则中分组的内容,所以使用 1 来表示正则中的第一个分组,后面的以此类推;这种方法类似字符串的拼接,用 1来表示正则中的第一个分组,后面的以此类推;这种方法类似字符串的拼接,用 1来表示正则中的第一个分组,后面的以此类推;这种方法类似字符串的拼接,用表示分组,其他的字符就是直接拼接
// 要求2:单词首字母转为大写,例如my name is allen, i like code.
var str = 'my name is allen, i like code.'
console.log(str.replace(/\b(\w)/g,function(m){return m.toUpperCase();
}))
// My Name Is Allen, I Like Code.
- 替换首字母,所以要用到\b来匹配边界,因为不确定个数,所以要用全局搜索,搜索全局的单词的边界
- m表示前面正则返回的边界字母,第二个参数传入一个函数,调用字符串的转大写方法将传入的字符转为大写,然后返回
用正则校验输入的为“大于0且只有两位小数”
var rg = /(0|[1-9]\d*)(\.\d{2})/