学习使用正则表达式

正则表达式很早就有了解,有需要的时候,也能借助搜索引擎简单使用一下,但似乎从来没有比较系统的学习过,所以这段时间看了一些资料,记录一下正则表达式的一些概念、用法以及 JS 中的相关 API。

字符组

字符组包含了要匹配字符的所有可能情况,使用[]表示,具体有如下三种描述方法

  1. 列举。即列举所有可能字符,如[abc]
  2. 范围。即使用范围表示所有可能字符,如 [a-z]
  3. 取反。在上面两种写法的基础上,在前面加上^表示取反逻辑,如[^abc]

对于常见的字符组,正则引擎内置了一些简写

  1. \d表示[0-9]
  2. \D表示[^0-9]
  3. \w表示[0-9a-zA-Z_]
  4. \W表示[^0-9a-zA-Z_]
  5. \s表示[ \t\v\n\r\f],\v 是垂直制表符,\f 是换页符
  6. \S表示[^ \t\v\n\r\f]
  7. .表示[^\n\r\u2028\u2029]表示几乎所有字符,除了换行符、回车符、行分隔符、段分隔符

量词

量词用来描述某个模式出现的次数,有两种描述方法

  1. {m,}表示至少出现 m 次
  2. {m}表示恰好出现 m 次

同样,对于常用的量词,引擎内置了一些简写

  1. ?表示{0, 1}
  2. +表示{1,}
  3. *表示{0,}

贪婪与非贪婪

先看一个例子

var regex = /\d{1,3}/g;
var string = "1 12 123 1234";
console.log(string.match(regex));
// -> ["1", "12", "123", "123", "4"]

\d{1,3}的意思是数字出现 1 到 3 次,但从结果可以观察到,这个模式会尽量多的匹配数字,即能匹配 3 个就不匹配两个,能匹配两个就不匹配一个。这种行为就是贪婪匹配。那么什么是非贪婪匹配的,在原来的例子上简单修改一下。

var regex = /\d{1,3}?/g;
var string = "1 12 123 1234";
console.log(string.match(regex));
// -> ["1", "1", "2", "1", "2", "3", "1", "2", "3", "4"]

匹配出来的结果都是一个数字,即能匹配一个就不匹配两个。通过上面的例子可以得到两个结论

  1. 量词默认是贪婪的
  2. 在模式后面加?可以将贪婪匹配变成非贪婪匹配

选择分支

语法是(p1|p2),表示模式 p1 或模式 p2。看个例子

var regex = /\d{3}|\d{5}/g;
var string = "12345";
console.log(string.match(regex));
// -> ["123"]

从这个例子也可以看出来,选择分支是非贪婪的,即 p1 满足了,就不再去尝试匹配 p2 了。

匹配位置

除了匹配字符,正则表达式的一个重磅功能就是匹配位置,即开头、结尾和字符之间的位置。一些常用的表示方法如下

  1. ^ 匹配开头,多行模式下匹配行开头
  2. $ 匹配结尾,多行模式下匹配行结尾
  3. \b 匹配\w 和\W 的位置,自然就有包括\w 和^以及\w 和\$之间的位置
  4. \B\b取反
  5. (?=p) 模式 p 前面的位置 positive lookahead
  6. (?!p) 上面的逻辑取反 negative lookahead

2019-5-30 更新,ES6 中新增了两个位置

  1. (?<=p) 模式 p 后面的位置 positive lookbehind
  2. (?<!p) 上面的逻辑取反 negative lookbehind

引用分组

()包裹起来的模式可以在正则表达式中和 JS 相关 API 中被引用,当被正则表达式引用时,使用\数字表示,在被 JS 相关 API 引用时,使用$数字表示,其中的数字范围从 1 到 99。

下面通过几个例子展示一下具体的用法

var regex = /\d{4}(-|\/)\d{2}\1\d{2}/;
var string1 = "2016-07-18";
var string2 = "2016/07/18";
var string3 = "2016-07/18";
regex.test(string1); // -> true
regex.test(string2); // -> true
regex.test(string3); // -> false

var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2016-07-18";
var result = string.replace(regex, "$2/$3/$1");
console.log(result); // -> 07/18/2016

元字符

在编写正则表达式时,遇到下面这 20 个字符,要记得转义

  1. \ | /
  2. () [] {}
  3. + - * =
  4. . , : ! ?
  5. ^ $

JS API

在 JS 中可以通过如下 API 使用正则表达式完成查找、替换、验证等操作

  1. regex.test(string)
  2. regex.exec(string)
  3. string.search(regex)
  4. string.match(regex)
  5. string.split(regex)
  6. string.replace(regex, string/function)

其他有趣的点

如果要匹配任意字符,可以使用逻辑取反操作来完成,比如[\d\D] / [\s\S][\w\W] / [^]

如果要写一个什么都匹配不了的模式,可以这样:/.^/即任意字符后面有个开头,这当然是不存在的


1271 Words

2016-07-18 20:40 +0800

comments powered by Disqus