正则表达式

入门

字符组

字符组[]允许匹配一组可能出现的字符

/[Jj]ava/g

// 匹配     Java8.0、java8.0
// 不匹配   jjva、Javv
// 匹配多个单词
/[Rr]ub[ye]/g

// 匹配     ruby、rube、Ruby on Rails、Rube on Rails
// 不匹配   rubb on rails、ruyye on rails、ruee、hello world

区间

在字符组中使用连字符-代表区间

  • 匹配任意数字[0-9]
  • 匹配所有小写字母[a-z]
  • 匹配所有大写字母[A-Z]
// 匹配数据所有的数字、小写字母和大写字母
/[0-9a-zA-Z]/g

// 匹配     abcdefg、012345678、987654321、ABCDEFG
// 不匹配   +_)*^$%、<>?:"{}、()。,/、?><,.>()

特殊字符

使用\对特殊字符进行转义

// 匹配特殊字符
/[\-\[\]\(\)]/g

// 匹配     []、-----、()、[]
// 不匹配   123456789、Abcdefg、code123、0codejn

取反

字符组开头使用^进行取反,就是匹配特定字符之外的任意字符

// 匹配`爱`后面不包含`你`的数据
/[^]/g

// 匹配     爱吗、爱哦、爱我自己
// 不匹配   我爱你、爱你、不爱你
// 匹配不包含小写字母的数据
/[^a-z]/g

// 匹配     01234、1234567890、CODEJIAONANG123、-*/124566ABV
// 不匹配   ab、abcd、pythonregext

快捷方式

  • 快捷匹配数字\d和单词字符\w
    • \w 与任意单词字符匹配,任意单词字符标识[0-9][a-z][A-Z]_
    • \d 与任意数字匹配[0-9]
/\w/g

// 匹配     master、code、hello world、987654321
// 不匹配   $#$%、<>()、//\
  • 匹配空白\s

\s可以匹配空白字符,比如空格,tab、换行等

/code\s/g
// 匹配     code 、code jiaonang、code jiaonang
// 不匹配   codeasd/、codejiaonangA$、CODEINFO
  • 单词边界\b

\b 匹配的是单词的边界

\bcode\b

// 匹配     code、code jiaonang、code jiaonang
// 不匹配   codeasd/、codejiaonangA$、CODEINFO
  • 快捷方式取反

    • \w取反\W
    • \s取反\S
    • \d取反\D
  • 开始^和结束$

^表示字符的开始,$表示字符的结束

/OS$/g
// 匹配     windows OS、Mac OS、LinuxOS、AppleOS
// 不匹配   OSopen、apple os
  • 任意字符.

.字符代表匹配任何单个字符,它只能出现在方括号以外,.字符只有一个不能匹配的字符,也就是换行符\n

// 匹配任意字母之后是ar的字符串
/.ar/g

// 匹配     ear、car、parked、garage
// 不匹配   aer、acer、acer
  • 可选字符?

?期望该字符出现零次或一次

// 匹配 favorite和favourite
/favou?rite/g

// 匹配     favorite、favourite
// 不匹配   favo、favrite、favouite

重复

一个字符组后加上{N} 就可以表示在它之前的字符组出现N次

// 匹配所有的电话号码
/\d{3}-\d{5}/g

// 匹配     010-88480、030-12345、030-98788
// 不匹配   20-66666、01-72813、123-123
  • 重复区间{M, N}

M是下界而N是上界

\d{3,4} 既可以匹配3个数字也可以匹配4个数字,不过当有4个数字的时候,优先匹配的是4个数字,这是因为正则表达式默认是贪婪模式,即尽可能的匹配更多字符,而要使用非贪婪模式,我们要在表达式后面加上?

/\d{3,4}?/g


// 0731  匹配到073
// 073   匹配搭配073
  • 开闭区间

\d{1,}闭区间不写即可表示匹配一个或无数个 - +等价于{1,} - *等价于{0,} - ?等价于{0,1}

// 匹配以f开头的数据
/^f\w+/g

// 匹配     f0asd...a123---、food、father
// 不匹配   f、brather、arathef、brathef
// 匹配以 http开头,以/结尾的所有数据
/^https?:\/\/.+/$/g

// 匹配     https://code.com/、http://codejn/、http://google.com/
// 不匹配   http:jn/code、master/、http、google.com

进阶

分组()

将表达式分组的机制,当使用分组时,除了获得整个匹配。还能够在匹配中选择每一个分组,分组有一个重要功能捕获数据,使用分组可以提取数据

// 0731-8825951
/(\d{3})-(\d{7})/g

// 捕获两段数据 (\d{3}):0731、(\d{7}):8825951
// 提取学号

// 需要匹配 2019-5013-08、2019 5013 08、2019501308。 需要提取的2019 5013 08
/(\d{4})[\-\s]?(\d{4})[\-\s]?(\d{2})/g
  • 分组或者条件|
// 提取所有的视频文件的后缀


/(.mp4|.avi|.wmv|.rmvb)/g

// 1.avi    =>  .avi
// abc.mp4  =>  .mp4
  • 非捕获分组(?:表达式)不会捕获表达式中的数据
// 提取目标数据中的电话号码
/(?:tel|\d{2,5})[\-:](\d{5})/g

// 01-75855     =>  75855
// 0731-75855   =>  75855
// 12345-75855  =>  75855 
// tel:75855    =>  75855
// 提取年月日的数据
/(\d{4})[\-.\s\/]?(\d{1,2})[\-.\s\/]?(\d{1,2})/g

// 2020-01-02   => 2020 01 02
// 2020-1-2     => 2020 1 2
// 2020.01.02   => 2020 01 02
// 2020 01 02   => 2020 01 02
// 2020 1 2     => 2020 1 2
// 20200102     => 2020 01 02
// 2020/01/02   => 2020 01 02
  • 分组回溯引用
// 0123<font>提示</font>abcd 

/<\w+>.*?<\/\w+>/g  // 0123<font>提示</bar>abcd   这个也能匹配到

/<(\w+)>.*?<\/\1>/  // \1就是对前面分组的引用
// 匹配符合 ab ba 这种关系的单词
/(\w)(\w)\2\1/g

// 匹配     abccba、allagmatic、otto、asffs
// 不匹配   aaruria、cffusive

断言

先行断言和后行断言为环视,也有人叫预搜索。先行断言从左往右看,后行断言从右往左看

  • 正向先行断言(?=表达式), 指在某个位置向右看,表示所在位置右侧必须能匹配表达式
// 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
// 如果要取出喜欢两个字,要求这个喜欢后面有你,这个时候就要这么写:
/喜欢(?=)/g
// 提取包含至少一个大小写字母的字符串
/(?=.*?[a-z])(?=.*?[A-Z]).+/g
  • 反向先行断言(?!表达式),指在某个位置向右看,表示所在位置右侧不能出现表达式
// 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
// 如果要取出喜欢两个字,要求这个喜欢后面没有你,这个时候就要这么写:
/喜欢(?!)/g
// 匹配不是qq邮箱的数据
/@(?!qq)/g
// 匹配除<p>或</p>之外的所有标签

/<(?!p)(.*)>.*</\1>/g

// 匹配     <div></div>、<h1></h1>
// 不匹配   <p></p>、<p>code</p>
  • 正向后行断言(?<=),指在某个位置向左看,表示所在位置左侧必须能匹配表达式
// 我喜欢你 我喜欢 我喜欢我 喜欢 喜欢你
// 如果要取出喜欢两个字,要求喜欢的前面有我,后面有你,这个时候就要这么写
/(?<=)喜欢(?=)/g
  • 反向后行断言(?<!),指在某个位置向左看,表示所在位置左侧不能匹配表达式
// 如果要取出喜欢两个字,要求喜欢的前面没有我,后面没有你
/(?<!)喜欢(?!)/g

总结

实例描述
[Pp]ython匹配 “Python” 或 “python”
rub[ye]匹配 “ruby” 或 “rube”
[abcdef]匹配中括号内的任意一个字母
[0-9]匹配任何数字。类似于 [0123456789]
[a-z]匹配任何小写字母
[A-Z]匹配任何大写字母
[a-zA-Z0-9]匹配任何字母及数字
[^au]除了au字母以外的所有字符
[^0-9]匹配除了数字外的字符
实例描述
.匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用 ‘[.\n]’ 的模式
?匹配一个字符零次或一次,另一个作用是非贪婪模式
+匹配1次或多次
*匹配0次或多次
\b匹配一个长度为0的子串
\d匹配一个数字字符。等价于[0-9]
\D匹配一个非数字字符。等价于[^0-9]
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [\f\n\r\t\v]
\S匹配任何非空白字符。等价于 [^\f\n\r\t\v]
\w匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’
\W匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]‘

参考

编程胶囊open in new windowRegexp playgroundopen in new window正则表达式不用背open in new window

Last Updated:
Contributors: fangjiebiao