Skip to content
kaba

正则表达式

1 min read

字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。 正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。

基本语法

在正则中,    如果直接给出字符,就是精确匹配。\d可以匹配一个数字,\w可以匹配一个数字或字母所以:

  • '00\d'可以匹配001,但无法匹配00A
  • '\d\d\d'可以匹配'123'
  • '\w\w'可以匹配'js'

.可以匹配任意字符:

  • 'js.'可以匹配'jsp''jsa''js#'

*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符

例1:\d{3}\s\d{3,8}

  • \d{3}表示3个数字,如'010'
  • \s表示一个空格
  • \d{3,8}表示3-8个数字,如'123','10000000'

进阶

要做更精确的匹配,使用[]表示范围:

  • [0-9a-zA-Z\_]匹配一个数字、字母或下划线
  • [0-9a-zA-Z\_]+匹配至少由一个数字、字母或下划线组成的字符串,如'a00''KABA_12''1234'
  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]*匹配字母数字下划线$开头,后接任意长度字符串
  • [a-zA-Z\_\$][0-9a-zA-Z\_\$]{0,19}匹配由字母数字下划线$开头后接0-19长度的字符串

[A|B]匹配A或B,所以:(j|J)ava(s|S)cript匹配'javascript'`` 'Javascript' ``'javaScript' ``'JavaScript'

^表示行的开头,^\d表示以数字开头 $表示行的结束,[a-z]$表示以小写字母结束,+表示一个或多个

RegExp

JS中有两种方式创建一个正则表达式

  1. 直接通过/正则表达式/ 写出来
  2. 通过 new RegExp('正则表达式') 创建一个RegExp对象
1let reg1 = /ABC\-001/;
2let reg2 = new RegExp('ABC\\-001')
3reg1; // /ABC\-001/
4reg2; // /ABC\-001/ 第二种写法由于字符串的转义,两个\\其实是一个\

判断正则表达式是否匹配

1const reg = /^\d{3}\-\d{3,8}$/;
2reg.test('010-12345'); //true
3reg.test('010-1234x'); //false
4reg.test('010 12345'); //false

切分字符串

普通的spilit:

1'a b c'.split(' '); // ['a', 'b', '', '', 'c']

无法识别连续空格,使用正则:

1'a b c'.split(/\s+/); // ['a', 'b', 'c']
1'a,b, c d'.split(/[\s\,]+/); // ['a', 'b', 'c', 'd']
1'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']

分组

出了判断匹配外,正则还有提取子串的功能,用()表示的就是要提取的组: ^(\d{3})-(\d{3,8})$定义了两个组

1const reg = /^(\d{3})-(\d{3,8})$/
2reg.exec('010-12345'); // ['010-12345', '010', '12345']
3reg.exec('010 12345'); // null

exec()方法在匹配成功后,会返回一个Array,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串。失败返回null

贪婪匹配

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符:

1var reg = /^(\d+)(0*)$/;
2reg.exec('102300'); // ['102300', '102300', '']

由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。 必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:

1var re = /^(\d+?)(0*)$/;
2re.exec('102300'); // ['102300', '1023', '00']