正则表达式

一、简介

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为”元字符”)。
正则表达式的学习成本与效率成正比,因此非常有必要。特别时后期的代码简化部分。

二、语法

正则表达式的规则很复杂,需要由简入深仔细理解。

1.字面量字符和元字符

大部分字符在正则表达式中,就是字面的含义,/a/匹配a。这些字符就表示该字面量(如a),表示字面量字符

/egg/.test('new egg') //true

上面语句中的egg,就是字面量字符。匹配的就是egg

除了这些字面量字符外,还有一些具有特殊意义的字符。为元字符

1.点字符(.)

点字符(.)匹配除回车(\r)、换行(\n) 、行分隔符(\u2028)和段分隔符(\u2029)以外的所有字符。

/a.c/

上面语句中,匹配的ab中包含任意的一个字符(不包含上述任意一个字符的所有)。

2.位置字符

用来提示字符所在的位置

  • ^: 表示字符串的开始位置
  • $: 表示字符串的结束位置
    // egg必须在开始位置
    /^egg/.test('egg111') // true

    // egg必须在结束位置
    /egg$/.test('111egg') // true

    // 从开始到结束只有egg
    /^egg$/.test('egg') // true

3.选择符(|)

选择符号类似于逻辑符号的关系。

/egg1|egg2/.test('egg123') // true

上面语句必须匹配其中一个。

如果想使部分语句中添加选择符号,可以使用小括号。

/a(b|c)c/.test('abc') // true

看到上面语句中的第二个字符必须使b或者c

4.转义符()

在需要将特殊字符转换为字面量字符时需要用到,作为开发人员,对这个肯定相当熟悉。如匹配1+1,必须要用到。

/1\+1/.test('1+1') // true

正则表达式中,需要反斜杠转义的的,共有12个字符:^.[$()|*+?{\
特别注意,在使用RegExp方法生成正则对象时,转义需要使用两个斜杠,来完成一次转义。

5.字符类([])

字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。

/[abc].test('hello world') // false
/[abc].test('aef') // true

以下两个字符在字符类中有特殊含义。

脱字符(^)

[^]表示了除字符类中的字符,其他字符都可以匹配(与字符类相反的处理条件)。另外,脱字符必须在字符类的第一个位置才有意义,否则就是字面含义。

/[^abc].test('hello world') // true

相比与.字符,[^]可以表示一切字符,包括了换行符。

连字符(-)

用于连续字符的简意形式,描述一个字符范围。

/a-z/.test('b') // false
/[a-z]/.test('b') // true

需要注意,必须在字符类中使用,否则就是不同的字面量字符。并且连字符只连接了该字符的前后各一个字符。
[1-31] // 表示1-3,而非1-31

并且,连字符还可以指定Unicode字符的范围。
var str = "\u0130\u0131\u0132";
/[\u0128-\uFFFF]/.test(str)
// true

6.重复类

模式的精确匹配次数,使用大括号({})表示。{n}表示恰好重复n次,{n,}表示至少重复n次,{n,m}表示重复不少于n次,不多于m次。

/lo{2}k/.test('look') // true
/lo{2,5}k/.test('loooook') // true

7.量词符

量词符用来设定某个模式出现的次数。

  • ?: 问号表示某个模式出现0次或1次,等同于{0, 1}
  • *: 星号表示某个模式出现0次或多次,等同于{0,}
  • +: 加号表示某个模式出现1次或多次,等同于{1,}
    /lo?k/.test('lok') // true
    /lo?k/.test('lk') // true

    /lo+k/.test('lok') // true
    /lo+k/.test('look') // true
    /lo+k/.test('lk') // false

    /lo*k/.test('lk') // true
    /lo*k/.test('lok') // true
    /lo*k/.test('loook') // true
贪婪模式

上面的查询条件时:在查到下一个不匹配规则的情况下,停止查询。即贪婪模式。

var s = 'bbb';
// 贪婪模式
s.match(/b+/); // ["bbb"]

// 非贪婪模式
s.match(/b+?/); // ["b"]

看到第二个语句中,使用非贪婪模式下,只要满足条件,就不会继续向下匹配。

  • +?:表示某个模式出现1次或多次,匹配时采用非贪婪模式。
  • *?:表示某个模式出现0次或多次,匹配时采用非贪婪模式。
  • ??:表格某个模式出现0次或1次,匹配时采用非贪婪模式。

8.修饰符

给予正则表达式的附加规则,放在最尾部。

/test/i
/look/ig

g 修饰符

g修饰符表示全局匹配,加上后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。

var re = /b/;
var str = abbc;

re.test(str); // true
re.test(str); // true
re.test(str); // true

上面代码中,使用默认情况下,每次都是从字符串头部开始匹配。

var re = /b/g;
var str = abbc;

re.test(str); // true
re.test(str); // true
re.test(str); // false

加上g后,前两次成功,最后则失败了,是由于每次的匹配对象起始位置都是从上一次匹配成功的位置开始的,因此,在两次找到后的第三次报错。

i 修饰符

默认情况下,正则对象区分字母的大小写,加上i修饰符以后表示忽略大小写。

/abc/.test('ABC') // false
/abc/i.test('ABC') // true

看到在添加i后,就可以忽视大小写情况。

m 修饰符

m修饰符表示多行模式,会重置^$的功能。前面知道,这两者是匹配头部和尾部。
此处由于加入修饰符m,则会略有不同,此时会识别换行符\n

/world$/.test('hello world\n') // false
/world$/m.test('hello world\n') // true

/^hello/m.test('t\nhello world') // true

9.组匹配

正则表达式中的括号表示分组匹配。

/look+/.test('lookk') // true
/(look)+/.test('looklook') // true

匹配组(\n)

正则表达式内部还可以使用 \n 来饮用括号内部内容。n 从1开始匹配对应顺序的括号内容。

/(.)b(.)\1b\2/.test('abcabc') // true
/t((..)\2)\1/.test('tabababab') // true

\1匹配第一个括号内容,\2匹配第二个括号内容。注意这里匹配的是内容。第二个语句就是需要注意匹配的位置,\2匹配第二个括号(..)\1匹配第一个括号((..)\2)

非捕获匹配(?:x)

(?:x)为非捕获组,表示不返回该组匹配的内容,即匹配的结果中不计入这个括号。

var m = 'abc'.match(/(?:.)b(.)/);
m // ["abc", "c"]
var n = 'abc'.match(/(.)b(.)//);
n // ["a", "abc", "c"]
先行断言

x(?=y),先行断言。x只有在y前面才匹配,y不会被计入返回结果。先行断言中,括号内的内部不会被返回。

var m = '10%'.match(/\d+(?=%)/);
m // ["10"]
先行否定断言

x(?!y)称为先行否定断言。与先行断言相反,x只有不在y前面才匹配,y不会被计入返回结果。先行否定断言中,括号内的内容不会被返回。

var m = '1.'.match(/\d+(?!%)/);
m // ["10"]

2.特殊字符

正则表达式对一些不能打印的特殊字符,提供了表达方法。

  • \cX 表示Ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符。
  • [\b] 匹配退格键(U+0008),不要与\b混淆。
  • \n 匹配换行键。
  • \r 匹配回车键。
  • \t 匹配制表符 tab(U+0009)。
  • \v 匹配垂直制表符(U+000B)。
  • \f 匹配换页符(U+000C)。
  • \0 匹配null字符(U+0000)。
  • \xhh 匹配一个以两位十六进制数(\x00-\xFF)表示的字符。
  • \uhhhh 匹配一个以四位十六进制数(\u0000-\uFFFF)表示的 Unicode 字符。

3.预定义模式

部分范围的简写模式

  • \d 匹配0-9之间的任一数字,相当于[0-9]。
  • \D 匹配所有0-9以外的字符,相当于0-9
  • \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]。
  • \W 除所有字母、数字和下划线以外的字符,相当于A-Za-z0-9\_
  • \s 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f ]。
  • \S 匹配非空格的字符,相当于 \t\r\n\v\f
  • \b 匹配词的边界。
  • \B 匹配非词边界,即在词的内部。