JavaScript 正则表达式

创建一个正则表达式(/…/)

核心

JavaScript有两种方式创建一个正则表达式:一种是直接通过 /正则表达式/ 写出来,另一种是通过 new RegExp('正则表达式') 创建一个RegExp对象。

RegExp对象的 test() 方法用于测试给定的字符串是否符合条件,返回 true 或者 false

举例

用正则表达式切分字符串比用固定的字符更灵活。如果用户输入了一组标签,可能用逗号、分号或空格分隔,现在需要用正则表达式来把不规范的输入转化成正确的数组:

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

元字符(. \d \w \s)

核心

元字符大致分两种,一种是用来匹配文本的(比如 . ),另一只是正则表达式的语法所要求的(比如 []).

. 字符可以匹配任何单个的字符、字母、数字甚至 . 字符本身。

在匹配特殊字符(比如 []\+*? 等在正则表达式中有特殊含义的字符)本身时,需要用元字符 \ 转义。

空白字符

常用的空白字符主要有换行符(\n)、回车符(\r)、制表符(\t)。

其中 \r\n 匹配一个“回车+换行”组合,是 Windows 的文本行结束标签;Unix 只是用一个换行符来结束一个文本行。

使用 \r\n\r\n 可以匹配两个连续的行尾标签,即空白行。在Unix/Linux上使用 \n\n 匹配空白行。

字符类别

匹配数字:\d 表示任何一个数字字符(等价于 [0-9]) ; \D 表示任意一个非数字字符(等价于 [^0-9])。

匹配字母和数字: \w 表示任何一个字母数字字符(大小写均可)或下划线字符(等价于 [a-zA-Z0-9_]); \W 表示任意一个非字母数字字符(大小写均可)或下划线字符(等价于 [^a-zA-Z0-9_])。

匹配空白字符:\s 表示任何一个空白字符(等价于 [\f\n\r\t\v]);\S 表示任何一个非空白字符(等价于 [^\f\n\r\t\v]

举例

.a.\.xls 可以匹配文件名含a的以.xls结尾的文件。

字符区间([] ^)

核心

[] 用来定义一个字符集合,其含义是必须匹配该集合里的字符之一。

定义一个字符集合的具体做法有两种:一是把所有字符列举出来,二是用元字符以字符区间方式给出。

字符集合可以用 ^ 来取非,表示除了该字符集合里的字符,其他字符都可以被匹配。

注意,在字符集合里使用 .+ 这样的元字符将被解释为普通字符,不需要被转义,[\w.][\w\.] 的使用效果一样。

举例

[0-9a-zA-Z\_] 可以匹配一个数字、字母或者下划线(单个字符)。

[^0-9] 可以匹配任何不是数字的字符。

^[\u4e00-\u9fa5] 可以匹配汉字。

重复匹配(+ * ? {n,m})

核心

+ 匹配至少1个字符;* 匹配任意个字符(包括0个);? 匹配0个或1个字符;{n} 匹配 n 个字符;{n,m} 匹配 n~m 个字符。

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。加个?就可以让其变成非贪婪匹配(懒惰型)。

举例

[a-zA-Z\_\$][0-9a-zA-Z\_\$]* 可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$ 组成的字符串,也就是JavaScript允许的变量名。

\d{3,8} 表示3-8个数字,比如’1234567’。

living in <B>AK</B> and <B>HI</B><[Bb].*</[Bb] 匹配,得到 <B>AK</B> and <B>HI</B> ,而用 * 的懒惰版本 *? ,即 <[Bb].*?</[Bb] 匹配,可以得到 <B>AK</B><B>HI</B>

位置匹配(\b ^ $)

核心

单词边界

\b 用来匹配一个单词的开始或结尾,它匹配的是一个这样的位置:这个位置位于一个能够用来构成单词的字符(\w)和一个不能用来单词的字符(\W)之间。\b 只匹配一个位置,不匹配任何字符。\B 作用与 \b 相反,匹配一个前后都不是单词边界的连字符。

字符串边界

^ 匹配行字符串的开头; $ 匹配行字符串的结尾。

举例

The cat scattered his food all over the room\bcat\b 匹配,只会得到第二个单词 cat。用 \bcat 将会匹配以cat开头的任何单词。

js 也可以匹配 'jsp',但是加上 ^js$ 就变成了整行匹配,就只能匹配 'js' 了。

子表达式分组匹配(() |)

核心

除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)。

子表达式的常见用途是:对重复次数元字符的作用对象做出精确的设定和控制,对 | 控制符的 OR 条件做出准确定义。

如果正则表达式中定义了组,就可以在RegExp对象上用exec()方法提取出子串来。

exec()方法在匹配成功后,会返回一个Array,第一个元素始终是原始字符串本身,后面的字符串表示匹配成功的子串。

exec()方法在匹配失败时返回null

举例

^(\d{3})-(\d{3,8})$ 分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:

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

(19|20)\d{2} 匹配一个以19或20开头的4位数字,可以用来匹配年份。

全局匹配(g i m)

JavaScript的正则表达式中,g 表示全局匹配。

全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行 exec(),正则表达式本身会更新 lastIndex 属性,表示上次匹配到的最后索引。

全局匹配类似搜索,因此不能使用/^...$/,那样只会最多匹配一次。

正则表达式还可以指定 i 标志,表示忽略大小写,m 标志,表示执行多行匹配。

举例

1
2
3
4
5
6
7
8
9
10
11
var s = 'JavaScript, VBScript';
var re=/[a-zA-Z]+Script/g;

// 使用全局匹配:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10

re.exec(s); // ['VBScript']
re.lastIndex; // 20

re.exec(s); // null,直到结束仍没有匹配到

参考

  1. 正则表达式必知必会 . Ben Forta
  2. JavaScript教程-RegExp . 廖雪峰
坚持原创技术分享,您的支持将鼓励我继续创作!