正则表达式

本文介绍正则表达式以及JavaScript中正则相关的API。



介绍

正则表达式是regular expression(规则表达式),就是定义字符串规则的表达式,语法基于一种古老的perl语言,它描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

正则表达式并不是只有前端才有,很多后端语言也都支持正则,正则本身是独立于语言之外的。

JavaScript诞生的最初目的就是:验证!Netscape Navigator

当初的浏览器是用来浏览一些新闻之类的文字信息,那么对于字符串的操作就比较重要了,比如验证表单,模糊搜索等。

举个例子:
从杂乱字符串中找数字;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var str = 'dadf123dsafd33dfds;;;[]123dg;123'
var temp = '';
var arr = []
for(var i = 0 ; i < str.length ; i ++){
if(str.charAt(i) >= 0 && str.charAt(i) <= 9){
temp += str.charAt(i)
} else {
if (temp != '') {
arr.push(temp)
temp = '';
}
}
}
if(temp!=''){
arr.push(temp)
}
console.log(arr)

使用正则呢?

1
var arr=str.match(/\d+/g)

一句搞定。

一个理念:任何程序都可以不用正则表达式写出来。 但是根据懒人原则,怎么做不言而喻。

语法

第一种写法

1
2
3
var reg=new RegExp('a');
var str='abcdefg';
console.log(reg.test(str)); // 返回bool值true,代表是否匹配成功

第二种写法

1
2
3
4
// perl风格  古老的语言
var re = /a/
var str='abcdefg';
console.log(re.test(str)) // true

特殊字符

[ ] 中括号:匹配其中的某一个字符

[abcde] 匹配abcde其中任意一个

[a-z] 匹配所有小写字母

[0-9] 匹配任意一个数字

( ) 小括号:分组:小括号里面的内容作为整体进行匹配

小括号用于分组,竖线作为间隔代表“或者”的含义

/(ab) | (cd)/ 匹配’ab’ 或者 ‘cd’

/(a|b)cd/ 匹配 ‘acd’ 或者 ‘bcd’

注意:小括号、竖线不要放在 [ ] 内(无意义)

| : 或,跟js中的(||)一样

^:排除(除了) 类似js中的(!)

^ (不在中括号里)匹配字符串开头

$ 匹配结尾

/^ $/ 这样的正则代表完整匹配

转义字符:元字符

所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

元字符 含义 等价表达式
\d 数字 [0-9]
\D 非数字 [^0-9]
\w 数字,字母,下划线 [a-z0-9_A-Z]
\W 非数字,字母,下划线 [^a-z0-9_A-Z]
\s 空白字符
\S 非空白字符
. 全部字符
\b 匹配单词边界
\B 匹配 非 单词边界
\0(数字0) 匹配 NUL 字符
\n 匹配 换行符
\f 匹配 换页符
\r 匹配 回车符
\t 匹配 制表符
\v 匹配 垂直制表符
\u4e00 - \u9fa5 验证中文
\u718a\u5927\u6797 熊大林

量词

正则表达式的一个符号块只能匹配文本中的一个符号,如果要多次匹配那么我们就需要量词

量词 含义 等价表达式
{n} 匹配n次
{n,m} 最少n次,最多m次
{n,} 最少n次,最多不限
+ 最少1次,最多不限 {1,}
? 可有可无,最多一个 {0,1}
* 可以有也可以没有,个数不限 {0,}

/(ab|cd){2}/ 匹配字符串”ab” 或者 “cd” 的2次,或者abcd。也就是说:abab cdcd abcd cdab这四组字符能成功匹配。

修饰符

匹配大小写不一样的字母怎么办?我们可以使用 修饰符 i

正则对象中有第二个参数,可以传入对应的值,i 代表让正则不区分大小写;

1
2
3
// 下面两种写法是等价的
var re = new RegExp('a', 'i')
var re= /a/i

修饰符 g 代表全局查找

1
2
var reg = new RegExp('\d+', 'g')
var reg = /\d+/ g

m代表多行查找(必须与g一起使用,并且,当使用^和$模式时才会起作用)

直接量字符

正则中有一些字符本身是具有含义的,那么如果我们要匹配这个字符就需要用到 \ 转义

\/ 匹配 / \\ 匹配 \ \. 匹配 .
\* 匹配 * \+ 匹配 + \? 匹配 ?
\\匹配\ \|匹配| \( 匹配 (
\[ 匹配 [ \] 匹配 ] \{ 匹配 {
\} 匹配 } \’ 匹配 单引号 \” 匹配 双引号
\xxx 查找以八进制数 xxx 规定的字符 \xdd 查找以十六进制数 dd 规定的字符 \uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符

正则对象的API

test方法

该方法用来测试某个字符串是否与正则匹配,匹配就返回true,否则返回false

1
2
3
var reg = /a/
var str = 'abcdefg';
console.log(reg.test(str)); // true

compile

该方法的作用是能够对正则表达式进行编译,被编译过的正则在使用的时候效率会更高,适合于对一个正则多次调用的情况,如果对一个正则只使用一两次,那么该方法没有特别显著的效应。

1
2
3
4
5
6
7
var reg=/[abc]/gi
console.log(reg.test('a'))

reg=/[cde]/gi
reg.compile(reg)
console.log(reg.test('a'))
console.log(reg.test('a'))

exec

返回的是一个数组,数组元素为匹配的子字符串

1
2
3
4
var str = 'dadf123dsafd33dfds;;;[]123dg;123'
var reg = /\d+/
var arr = reg.exec(str)
console.log(arr) // ['123']

支持正则的字符串API

查找第一次匹配的子字符串的位置,如果找到就返回一个number类型的index值,否则返回-1

replace

该方法用来将字符串中的某些子串替换为需要的内容,接受两个参数,第一个参数可以为正则或者子字符串,表示匹配需要被替换的内容,第二个参数为被替换的新的子字符串

split

将一个字符串拆分成一个数组,它接受一个正则或者子字符(串)作为参数,返回一个数组

match

接收一个正则作为参数,用来匹配一个字符串,返回一个数组

案例

  • 固话规则 0421-6600656
    开头为0的2或者三位数字加上 - 开头为非零的八位数字结尾是1到4位的分机号

    /^0\d{2,3}-[1-9]\d{7}\d{1,4}?$/

  • 邮箱验证

    /^[0-9a-z]\w+@[0-9a-z]+\.[0-9a-z]+$/i

  • 匹配网址URL的正则表达式

    /^http(s)?:\/\/[a-z]{3,5}\.\w+\.\w+(\/.+)*$/

  • 配首尾空格的正则表达式

    /^\s+.*\s+$/

  • 匹配双字节字符(包括汉字在内)

    [^\x00-\xff]

  • 只能输入汉字

    [\u4e00-\u9fa5]

  • 删除多余空格

    str.replace(/\s+/g,'')

  • 删除首尾空格

    str.replace(/^\s+/,'')

    str.replace(/\s+$/,'')

正则练习

  1. 只能用数字开头,长度在6–18位之间
  2. 以字母开头,数字结尾,中间任意一个字符
  3. 密码不能少于6位的字符
  4. 以a开头 b字符至少出现2个,至多出现6个(b连续出现)
  5. 变量的命名正则表达式(不能用数字开头 由字母、数字、下划线 、$组成)
  6. 以010开头的座机号(后面是8位数字)
  7. 手机号以13开头,以8结尾
  8. 密码只能用6个*
  9. 第一位是数字,第二位是A或a,后面至多出现6个字符
  10. 第一位是数字,第二位是任意一个字符,后面只能由字母、数字、下划线组成,共8位
  11. 写出中国人姓名正则 2–4个中文
  12. 写一个qq号的正则,至少5位 至多12位数字
  13. 邮编检验 共6位数字 第一位不能是0
  14. 检验压缩包 xxx.zip或xxx.rar或xxx.tar 三个格式
  15. 手机号 1 3|4|5|6|8|7|9
  16. 账户名只能使用数字字母下划线,不能数字开头,长度在6–18之间

身份证 (18位 考虑最后一位可能为x)

/^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$|^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/

练习答案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1. /^\d.{5,17}$/
2. /^[a-z].\d$/i
3. /.{6,}/
4. /^a[^b]*b{2,6}[^b]*$/
5. /^[a-z_\$][\w\$]*$/i
6. /^010\d{8}$/
7. /^13\d{8}8$/
8. /^\*{6}$/
9. /^\da.{0,6}$/i
10. /^\d.\w{6}$/
11. /^[\u4e00-\u9fa5]{2,4}$/
12. /^[1-9]\d{4,11}$/
13. /^[1-9]\d{5}$/
14. /\.(zip)|(rar)|(tar)$/
15. /^1[3-9]\d{9}$/
16. /^[a-z_]\w{5,17}$/i

扩展:贪婪模式和惰性模式

贪婪量词: 贪婪模式尽可能多的匹配

? * + {n} {n,m} {n,}

惰性量词: 惰性模式尽可能少的匹配

?? *? +? {n}? {n,m}? {n,}?

用惰性量词进行匹配时,它首先将第一个字符当成一个匹配,如果成功则退出,如果失败,则测试前两个字符,依次增加,直到遇到合适的匹配为止;

贪婪量词与惰性量词的方法正好相反,如果符合要求就一直往后匹配,一直到无法匹配为止,惰性量词仅仅在贪婪量词后面加个”?”而已。如”a+”是贪婪匹配的,”a+?”则是惰性的。

var str="abbbbcc"

贪婪: /[ab]+b/ 结果:abbbb

惰性: /[ab]+?b/ 结果:ab

例子:

1
2
3
4
5
var str = 'aabbazbbwwbbaa';
var arr =str.match(/.bb/);
console.log(arr) //aabbazbbwwbb,贪婪的
var arr1 =str.match(/.?bb/g);
console.log(arr1)//aabb azbb wwbb 返回一个数组包含3个值,惰性的

代码不是万能的,但不写代码是万万不能的

Dary记


  • 更多干货,尽在公众号



转载请注明来源,文末有原始链接。欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 dary1112@foxmail.com

创作不易,您的打赏是我更新的动力

  • 支付宝

  • 微信

文章标题:正则表达式

文章字数:2.4k

本文作者:Dary

发布时间:2020-03-17, 18:51:00

最后更新:2020-10-22, 17:03:52

原始链接:http://www.xiongdalin.com/2020/03/17/RegExp/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录