正则表达式总结

166 阅读2分钟

在线验证工具

regulex
regexper
pyregex
在线校验

字符

元字符

元字符描述
.匹配除换行符以外的任意字符
\d匹配数字, 等价于字符组[0-9]
\w匹配字母, 数字, 下划线
\s匹配任意的空白符(包括制表符,空格,换行等)
\b匹配单词开始或结束的位置
匹配行首
$匹配行尾
\D匹配非数字的任意字符, 等价于[^0-9]
\W匹配除字母,数字,下划线之外的任意字符
\S匹配非空白的任意字符
\B匹配非单词开始或结束的位置
[^x]匹配除x以外的任意字符
*x>=0
+x>=1
?x=0 or x=1
{n}x=n
{n,}x>=n
{n,m}n<=x<=m

字符组

[…] 匹配中括号内字符之一. 如: [abc] 匹配字符 a, b 或 c;如果中括号中包含元字符或限定符, 则元字符或限定符降级为普通字符, 不再具有元字符或限定符的功能, 如 [+.?] 匹配 加号, 点号或问号。

如果[]中出现-

  • 如果是[0-9a-zA-Z],-则表示的是一个区间,0到9、a到z、A到Z,不会匹配到-
  • 如果是要匹配到-,则加上转义符 \ 即可

排除性字符组

[^…] 匹配任何未列出的字符; 如: [^a] 匹配除a以外的任意字符。

多选结构

| 就是或的意思,表示两者中的一个;如: x|y 匹配x或者y字符。

括号

() 常用来界定重复限定符的范围,以及将字符分组;如: (ab)+ 可以匹配abab..等, 其中 ab 便是一个分组。

转义字符

** 即转义字符, 通常 \ * + ? | { [ ( ) ] }^ $ . # 和 空白 这些字符都需要转义.

操作符的运算优先级

  1. \ 转义符
  2. (), (?:), (?=), [] 圆括号或方括号
  3. *, +, ?, {n}, {n,}, {n,m} 限定符
  4. ^, $ 位置
  5. | “或” 操作

修饰符

javaScript中正则表达式默认有如下五种修饰符:

  1. g (全文查找), 如上述截图, 实际上就开启了全文查找模式.
  2. i (忽略大小写查找)
  3. m (多行查找)
  4. y (ES6新增的粘连修饰符)
  5. u (ES6新增)

测试

我们来测试下上面的知识点, 写一个匹配手机号码的正则表达式, 如下:

(\+86)?1\d{10}
  1. “+86” 匹配文本 “+86”, 后面接元字符问号,,表示可匹配1次或0次, 合起来表示 “(+86)?” 匹配 “+86” 或者 “”
  2. 普通字符”1” 匹配文本 “1”
  3. 元字符 “\d” 匹配数字0到9,区间量词 “{10}” 表示匹配 10 次,合起来表示 “\d{10}” 匹配连续的10个数字

以上, 匹配结果如下:

image.png

贪婪模式和非贪婪模式

默认情况下, 所有的量词 *、 +、? 或 {}都是贪婪模式, 表示尽可能多的去捕获字符; 而在量词后增加 ? , 则是非贪婪模式, 表示尽可能少的去捕获字符. 如下:

var str = 'aaab';

str.match(/a+/)  // ["aaa", index: 0, input: "aaab", groups: undefined]
str.match(/a+?/) // ["a", index: 0, input: "aaab", groups: undefined]
str.match(/a{2,3}/) // ["aaa", index: 0, input: "aaab", groups: undefined]
str.match(/a{2,3}?/) // ["aa", index: 0, input: "aaab", groups: undefined]

在String.prototype.replace()中运用正则表达式

replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。

语法
str.replace(regexp|substr, newSubStr|function)
  • regexp (pattern):一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。
  • substr (pattern):一个将被 newSubStr 替换的 字符串。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替换。
  • newSubStr (replacement):用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数。
  • function (replacement):一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数。
tip: 在进行全局的搜索替换时,正则表达式需包含 g 标志。
第一个参数是正则时的几种情况
  1. 第一个参数是正则,第二个参数是带$符的字符串
    var str3 = '这是一段原始文本,"3c这要替换4d"!';
    var newStr = str3.replace( /([0-9])([a-z])/g,"$1" );
    console.log( newStr );    //输出:    这是一段原始文本,"3这要替换4"!';

替换字符串可以插入下面的特殊变量名:

变量名代表的值
$$插入一个 "$"。
$&插入匹配的子串。
$`插入当前匹配的子串左边的内容。
$'插入当前匹配的子串右边的内容。
$n假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从1开始。如果不存在第 n个分组,那么将会把匹配到到内容替换为字面量。比如不存在第3个分组,就会用“$3”替换匹配到的内容。
$Name这里Name 是一个分组名称。如果在正则表达式中并不存在分组(或者没有匹配),这个变量将被处理为空字符串。只有在支持命名分组捕获的浏览器中才能使用。
  1. 第一个参数是正则,第二个参数是函数 你可以指定一个函数作为第二个参数。在这种情况下,当匹配执行后,该函数就会执行。 函数的返回值作为替换字符串。 (注意:上面提到的特殊替换参数在这里不能被使用。) 另外要注意的是,如果第一个参数是正则表达式,并且其为全局匹配模式,那么这个方法将被多次调用,每次匹配都会被调用。

函数的参数:

变量名代表的值
match匹配的子串。(对应于上述的$&。)
p1,p2, ...假如replace()方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的11,2等。)例如,如果是用 /(\a+)(\b+)/ 这个来匹配,p1 就是匹配的 \a+,p2 就是匹配的 \b+
offset匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc',那么这个参数将会是 1)
string被匹配的原字符串
NamedCaptureGroup命名捕获组匹配的对象

(精确的参数个数依赖于 replace() 的第一个参数是否是一个正则表达式(RegExp)对象,以及这个正则表达式中指定了多少个括号子串,如果这个正则表达式里使用了命名捕获, 还会添加一个命名捕获的对象)

    var str = '测试文本1a测试文本2b';
    
    var newStr = str.replace( /([0-9])([a-z])/g,function (match, p1, p2, offset, string){
      console.log( match );
      console.log( p1 );
      console.log( p2 );
      console.log( offset );
      console.log( string );
    } );
    //输出:
    1a
    1
    a
    4
    测试文本1a测试文本2b
    2b
    2
    b
    10
    测试文本1a测试文本2b
    function replacer(match, p1, p2, p3, offset, string) {
      
      return [p1, p2, p3].join(' - ');
    }
    
    var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
    
    console.log(newString);  // abc - 12345 - #$*%