Regular Expression in Javascript

正则语法

  • 句点 . 代表除换行符以外的任意字符
  • 括号 [] 代表字符合集
  • 次方符号 ^ 在 [] 内时代表取非运算
  • 次方符号 ^ 在正则开头时表示字符串前边界
  • 美元符号 $ 在正则开头时表示字符串后边界
  • 连词符 - 代表字符序列
  • 竖线 | 代表或操作符
0-9 // 数字 0123456789  
a-z // 小写字母 abcd...xyz  
A-Z // 大写字母 ABCD...XYZ

A-F // 字母 ABCDEF

A-z  
// ASCII字符 A-z 
// 注意包含介于 Z 和 a 中间的 [ ^ 等字符
  • 反斜杠 \ 代表转义
\. // 表示匹配句点 .
  • 空白元字符为 \s
\f // 换页符
\n // 换行符
\r // 回车符
\t // 制表符 即 Tab 键
\v // 垂直制表符

// 这些都属于 \s 范畴
// 与之对应 \S 相当于 [^\s]
  • 数字字符 \d
  • 与之对应非数字字符为 \D
\d // 数字 0123456789
  • 数字字母与下划线的集合 \w
  • 非数字字母与下划线的集合 \W
\w // 数字 大小写字母 和 下划线 _
  • \x 开头为十六进制
  • \0 开头为八进制

  • 加号 + 代表一个或多个字符

[0-9]+
// 可以匹配到 0 或是 123 又或是 10086
  • 星号 * 代表零个或多个字符
[0-9]*@
// 可以匹配到 123@ 或是 10086@ 又或是不包含数字的 @
  • 问号 ? 代表零个或一个字符
[0-9]?@
// 可以匹配到 1@ 或是 8@ 又或是不包含数字的 @
  • 大括号 {} 可以给一个长度区间
[0-9]?{6}
// 代表字数为 6 的数字序列
// 可以匹配到 000000 到 999999 的数字

[0-9]?{2,6}
// 代表字数为 2 到 6 的数字序列
// 可以匹配到 00 到 999999 的数字

[0-9]?{2,}
// 代表字数为 2 到 无限 的数字序列
// 可以匹配到 00 到 任意长 的数字
  • 将贪婪正则转换为懒惰正则
<span>A</span>B<span>C</span>

// 我们期盼匹配到 <span></span> 标签对

// 如果正则这么写 [<span>].*[</span>]
// 匹配结果错为 <span>A</span>B<span>C</span>

// 应该将贪婪正则转换为懒惰正则
// 正则这么写 [<span>].*?[</span>]
// 匹配结果正确为 <span>A</span> 和 <span>C</span>

// 常见的贪婪匹配有 + * 和 {n,} 其中 n 为正整数
// 它们都可以借由 ? 转换为懒惰正则
  • 边界匹配 \b
class com extend components {}

// 我们期盼匹配到单词 com

// 如果正则这么写 com
// 匹配结果会包含 components 的 com

// 如果正则这么写 [\bcom\b]
// 匹配结果只包含左右都有边界的单词 com
// 注意只有 com 三个字符而不包含左右空格

// 与此对应 \B 会匹配非单词边界

123 4 5  
// 如果正则这么写 [\B0-9\B]
// 匹配结果为 2
  • 开启分行匹配模式 (?m)
// TODO
class com extend components {  
  // some comment
}

// 我们期盼匹配到这两句注释

// 如果正则这么写 ^\s[//\s?*]$
// 匹配结果只有第一条注释 // TODO

// 那么我们应该开启分行匹配模式 (?m)^\s*//\s?$
// 匹配结果包含了所有两句注释
  • 子表达式 ()
Mac&nbsp;&nbsp;OS

// 我们期盼匹配到 &nbsp;
// &nbsp;{2,} 会匹配出错误结果
// 因为 {2,} 作用在分号 ; 上了

// 所以我们应该用 (&nbsp;){2,}
  • 回溯引用 \1 \2 \3 ...
a b c c d e f f g h h i j k k

// 我们期盼匹配到所有重复字母
// (\b\w)\1
// 成功匹配到 c c f f h h k k
// \1 表示取该正则内 第一个 子表达式匹配到的值
// \2 \3 ... 亦然
  • 向前查找 (?=)
http://example.com

// 我们期盼匹配到 http
// [a-zA-Z]+(?=:)
// 成功匹配到 http
// (?=:) 表示以 : 为准向前查找
// 返回结果不包含 :
  • 向后查找 (?=)
¥100.00

// 我们期盼匹配到 100.00
// (?<=¥)[0-9\.]+
// 成功匹配到 100.00
// (?<=¥) 表示以 ¥ 为准向后查找
// 返回结果不包含 ¥
  • 向前查找取非 (?!)

  • 向后查找取非 (?

  • 条件查找 ?(1) ?(2) ?(3) ...

(123)
(123
123)  
123

// 我们期盼匹配到 (123) 和 123
// 排除括号不完整的字符串
// (\()?123(?(1)\))
// ?(1) 表示前一个子表达式 (\()? 是否存在
// 只有 (\()? 匹配到 ( 了 ?(1) 之后的 \) 才会被匹配

在字符集合 [] 里写句点 . 或是加号 + 等字符都不会被当做元字符而是会取其本意。换句话说,在字符集合 [] 里匹配句点 . 或是加号 + 是不需要用 \ 转义的。

还有 POSIX 字符类,不过 Javascript 不支持该类正则,这里就不展开了。

Js 中的正则

Js 中的正则有两种表示形式,通过 new 关键字创建或者是使用 // 字面量表示,如下。第二个参数有三个取值,g - 全文查找 i - 忽略大小写 m - 多行查找

var myReg = new Reg('a', 'gi')

var myReg = /a/gi  

Js 中正则的使用场景大致为以下几种。

RegExp.prototype.exec(string)

RegExp.prototype.test(string)

RegExp.prototype.toString()

String.prototype.match(regexp)

String.prototype.search(regexp)

String.prototype.replace(searchValue, replaceValue)

String.prototype.split(separator, limit)