你需要的一份javascript正则入门篇

117 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

定义正则

定义正则有两种方式:

  • new RegExp('a'): RegExp对象,参数就是我们想要制定的规则,这种方式适合规则是动态
  • /a/: 简写,但是不能动态定义规则

这两种方式有时候在写法上有些区别,比如在匹配空格时需要加转义字符\

/\s/ 这样写即可 
new RegExp('\\s') 这里必须要加一个转义

正则表达式模式

方括号

js9.jpg

元字符

js10.jpg

数量匹配

  • ? :匹配0或者1个
  • * :匹配0个或者多个
  • + :匹配1个或者多个

正则的方法

test

在字符串中查找符合正则的内容,若查找到返回true,反之返回false。

var str = '374829348791'
// \D代表非数字
var re = /\D/ 
if (re.test(str)) {
  // 返回true,代表在字符串中找到了非数字。
  console.log('不全是数字')
} else {
  console.log('全是数字')
}

exec

和match方法一样,搜索符合规则的内容,并返回内容,格式为数组。

js8.jpg

数组的第一项代表匹配的内容,第二项代表子项,即()里面匹配的内容。

如果想要全局匹配,首先var re = /test(\d+)/g, 表示全局匹配,然后不断的调用re.exec(testStr),它就会匹配下一个。

js7.jpg

字符串使用正则的方法

search

在字符串搜索符合正则的内容,搜索到就返回出现的位置, 如果搜索失败就返回 -1。

在字符串中找字母b,且不区分大小写:

var str = 'abcdef';
var re = /B/i;
// var re = new RegExp('B','i'); 也可以这样写
console.log( str.search(re) ); // 1

match

在字符串中搜索符合规则的内容,搜索成功就返回内容,格式为数组,失败就返回null。

找出指定格式的所有数字,如下找到 123,54,33,879

var str = 'haj123sdk54hask33dkhalsd879'; 
var re = /\d+/g;
console.log( str.match(re) ); // [123,54,33,879]

每次匹配至少一个数字 且全局匹配 如果不是全局匹配,当找到数字123,它就会停止了,就只会弹出123。加上全局匹配,就会从开始到结束一直去搜索符合规则的。

如果没有加号,匹配的结果就是1,2,3,5,4,3,3,8,7,9并不是我们想要的,有了加号,每次匹配的数字就是至少一个了。

replace

查找符合正则的字符串,就替换成对应的字符串,返回替换后的内容。

stringObject.replace(regexp/substr, replacement)

replacement: 要么是一个替换文本的字符串,要么是一个生成替换文本的函数

敏感词过滤

var str = '我爱北京天安门,天安门上太阳升。'
var re = /北京|天安门/g
var str2 = str.replace(re, function (str) {
  // 函数的第一个参数代表每次搜索到的符合正则的字符,
  // 所以第一次str指的是北京 第二次str是天安门 第三次str是天安门
  console.log('str', str)
  var result = ''
  for (var i = 0; i < str.length; i++) {
    result += '*'
  }
  return result //所以搜索到了几个字就返回几个*
})
console.log(str2) //我爱*****,***上太阳升

特殊符号

  • $&: 与正则相匹配的字符串
  • 1,1,2,3,,3,…,n: 匹配结果中对应的分组匹配结果
'abc'.replace(/b/, "$&123") // 'ab123c'
'sjn@163.com'.replace(/(.+)(@)(.*)/,"$2$1") // '@sjn'
'sjn@163.com'.replace(/(.+)(@)(.*)/,"$3$2$1") // '163.com@sjn'

案例

小驼峰转化为中划线

把abCd转化为ab-cd

'abCd'.replace(/[A-Z]/g, c => `-${c.toLocaleLowerCase()}`)

把中划线转化从小驼峰

const camelizeRE = /-(\w)/g
const str = 'name-space'
const str1 = str.replace(camelizeRE, (_, c) => {
  console.log('_', _) // _s
  console.log('c', c) // s 代表分组的内容
  return c ? c.toUpperCase() : ''
})
console.log(str1)

/(?:^|\/)\.?\.$/

分析/(?:^|\/)\.?\.$/所表示的具体含义

  • .表示匹配任何字符,但是这里只想匹配点这个字符,所以加了反斜杠,进行转义
  • ()括号表示分组
  • (?:) 非捕获分组:也就是不会把分组的内容匹配出来
  • /^/ 匹配空;/^A/ 匹配开头的A;/[^A]/ 匹配除A以外的其他字符

这个正则所匹配的内容是/.. /.

拿到13px 9.5px里面的数字

const reg = /^(\d+(\.\d+)?)px$/ 
const arr = val.match(reg)

js11.jpg 非捕获分组 js12.jpg

js13.jpg

密码包含数字,字母和特殊字符

const reg = /^.*(?=.{8,})(?=.*\d)((?=.*[A-Z])|(?=.*[a-z]))(?=.*[!@#$%^&*?\\(\\))]).*$/

正向先行断言 (?= ): 这是一个先行断言,用以说明圆括号内的表达式必须正确匹配。比如:/Java(?=:)/ 只能匹配Java且后面有冒号的。

(?=.*[!@#$%^&*?()]): 该断言表示,必须包括一个特殊字符。上述表达式中的10个特殊字符为键盘1,2...0的上档键字符,也可以添加别的特殊字符。

匹配千分位

function format(v) { 
    const reg = /\d{1,3}(?=(\d{3})+$)/g 
    return v.replace(reg, '$&,') 
}

?=(\d{3}+)$,表示最后的数字是3个一组,即只有最后面的是数字是三个一组那么就是匹配上了。

var str = '1234567890'

首先最后三个数字是 234 567 890 前面是1,也就是当前面是1的时候,后面满足?=的条件,那么1就是合格的;

匹配完1之后,剩下的数字是'234567890',把2拿出来,剩下的是345 678 90 显然不满足?=的条件,那么接着匹配;

匹配23,后面的是 456 789 0 显然也不行;

匹配234,后面是567 890 满足?=的条件,所以234 是合格的;

直接继续匹配,最后只有1, 234, 567能满足要求,只要当前面的数字是1,234, 567的时候,后面的模式是满足的。

var str = '1234567890' 
var reg = /\d{1,3}(?=(\d{3})+$)/g 
str.match(reg) // [1, 234, 567]

匹配出来后,进行替换$&表示匹配替换的内容,也就是1 或者234 或者567, 那么在后面加个逗号就行了:

str.replace(reg, '$&,')

正则匹配有个特点,如果是全局匹配,如果第一次匹配上了,那么把匹配的值去掉,剩下的再进行匹配。

匹配空格换行

str.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '')

[\r\n]匹配回车和换行,/^\s+|\s+$/gm匹配空格。

推荐一个验证正则的网站:regexr.com/