平时在使用一些正则都是网上拷贝下来的,知其用而不知道所以然,现在发现得好好学习一下正则表达式了。
在学习正则之前,我们得先了解一些正则的元字符,,然后才能继续看下文
RegExp对象
声明一个正则有两种写法
let re = /[\d]+/g;
let re1 = new RegExp('[\\d]+', 'g');
两者的区别就是,new RegExp的第一个参数字符串的转义字符要两个斜杠,第二个参数是修饰符,i/g/m,具体查看文档
正则方法
正则对象有三个方法,分别为test(),exec(),compile()
test()检索字符串是否有对应的值,返回true或false
比如检查input输入是否合法,不需要获取匹配值,可以使用test()方法
let reg = /[\w]+/; // 只能是数字或者字符串和下划线
reg.test('肯德基'); // false
reg.test('aa_123'); // true
exec()检索字符串的指定值,返回null或者数组
比如我们要获取匹配的指定值,可以使用exec
/abc/.exec('a'); // null
/abc/.exec('dcba abc qwer abc'); // 匹配第一个就停止,返回 ['abc']
如果需要匹配子项的话
/(ab)c/.exec('dcba abc qwer abc'); // 返回一个数组,第二个参数是括号的内容 ['abc', 'ab']
上面的例子匹配到第一个就会停止了,如果要继续匹配,可以使用while循环,正则需要加上g修饰符,如果没有会死循环
let re = /abc/g, ret;
while (ret = re.exec('dcba abc qwer abc')) {
console.log(ret)
}
// 分别打印出以下结果,由于使用了全局匹配,会返回额外的index和input结果
// ["abc", index: 5, input: "dcba abc qwer abc"]
// ["abc", index: 14, input: "dcba abc qwer abc"]
compile()可以执行,改变和重新编译正则表达式
该方法可以复用一个对象,在代码执行的过程中重新改变匹配方式,用的地方相对较少
正则应用
这里举一个例子,例如需要校验用户名是否符合需求
需求:用户名以字母开头+数字/字母/下划线,长度不小于6不大于12
分析:
- 以字母开头的正则
^[a-zA-Z] - 数字/字母/下划线的正则 \w ==>
[a-zA-Z0-9_] - 由于首字母占用一位,剩下5-11个长度,
{5,11}$
通过上面的分析,可以合并为一个表达式: /^[a-zA-Z]\w{5,11}$/
贪婪模式
贪婪模式会匹配尽可能多的字符,比如
let ret = /a+/.exec('aaaaaa') // ["aaaaaa", index: 0, input: "aaaaaa", groups: undefined]
上面的正则会尽量去匹配多个字符,结果返回的是 aaaaaa
非贪婪模式
非费贪婪模式会尽量少的匹配,只需要在修饰符后面加上?即可
// 很懒,只匹配到一个就停止了
let ret = /a+?/.exec('aaaaaa') // ["a", index: 0, input: "aaaaaa", groups: undefined]
非贪婪模式的使用场景,比如有这样的html字符串
let html = "<div>div1</div><div>div2</div>"
我们想取<div>div1</div>字符串,获取你想这样写
let ret = /<div>.*<\/div>/.exec(html) // "<div>div1</div><div>div2</div>"
结果返回的是整个html字符串,这时候非贪婪模式就可以派上用场了
let ret = /<div>.*?<\/div>/.exec(html) // "<div>div1</div>"
再举个例子,比如要截取一个图片"a.jpg.jpg.png"字符串的"a.jpg"
let url = "a.jpg.jpg.png";
let ret = /.*?\.jpg/.exec(url) // a.jpg
String.replace
String.replace()可以使用正则来替换字符串,例如
let str = "abc you abc me";
str.replace(/abc/g, 'fuck'); // fuck your fuck me
第二个参数还可以是回调函数,于是上面的写法还可以这样写
let str = "abc you abc me";
str.replace(/abc/g, match => {
// match是正则匹配到的字符串
return 'fuck';
})
String.replace和while循环
例如我们想要获取url的所有字符串,我们可能会这么写
let url = "ttp://a.com?a=1&b=abc&q=%e5%b0%bc%e7%8e%9b&名字=xx";
let reg = /[\?&]([^&#]+)=([^&#]*)/g, params = {}, ret;
// 使用while
while (ret = reg.exec(url)) {
params[ret[1]] = ret[2];
}
console.log(params);
[^&#]表示除了&和#外的所有字符
String.replace在全局模式下,第二个参数回调会一直调用知道搜索结束,所以可以这样写
let url = "ttp://a.com?a=1&b=abc&q=%e5%b0%bc%e7%8e%9b&名字=xx";
let reg = /[\?&]([^&#]+)=([^&#]*)/g, params = {}, ret;
// 使用replace
url.replace(reg, (match, sub1, sub2) => {
params[sub1] = sub2;
})
console.log(params);
正向肯定预查
(?=pattern)是正向肯定预查,例如:Windows(?=98|2000) 可以匹配Windows2000的Windows,不可以匹配Windows2008的Windows
利用这个规则可以实现匹配大小写和数字的正则
let reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[\d]).{6,12}$/
原文地址:js正则 有问题可以在原文底下发表您的意见o~~hohoho