https://zhuanlan.zhihu.com/p/57149231
https://jex.im/regulex/#!flags=&re=%5E(a%7Cb)*%3F%24*%3F%24)

语法

^ 字符串的开始
$ 字符串的结束
/b 单词边界,单词的开始或结束
/d 数字,[0-9]
/D 非数字,[^0-9]
/w 任意数字,字母,下划线,[0-9A-Za-z_]
/W 非数字,字母,下划线,[^0-9A-Za-z_]
/s 空白字符
/S 非空白字符
* 重复零次~多次
+ 重复一次~多次
? 重复零次或一次
() 分组
[] 字符类
. 非换行的任意字符
{n} 重复n次
{n,} 重复至少n次
{n,m} 重复n次到m次
|

i:忽略大小写
g:全局匹配
m:多行
v2-5ab2db84fb13a9fc6d5627aca9f04880_r.jpg

  1. let quit = "qu";
  2. let noquit = "qt";
  3. let quRegex= /q(?=u)/;
  4. let qRegex = /q(?!u)/;
  5. quit.match(quRegex); // Returns ["q"]
  6. noquit.match(qRegex); // Returns ["q"]

先行断言

先行断言的语法形式为 /c(?=a)/,表示匹配 a 左边的 c。为了避免与断言中的「前」和 「后」混淆,这里就用「a 左边的 c」来表达。
image.png
先行断言有些地方也叫「前瞻断言」或「前向查找」,想象你自己就是一个指针,扫描字符串的过程就像指针在向前移动。

先行断言也有其否定形式,叫做先行否定断言,如 /c(?!a)/,即匹配「非a」左边的 c,其实这与 /c(?=[^a])/ 效果相同

(?:pattern):表示匹配 pattern,但不获取匹配的子字符串

正向先行断言
(?=...)...表示需要存在但不会被匹配到的部分
负向先行断言
(?!...)...表示希望不存在的匹配模式

更实际的用途:检查一个字符串的两个或更多匹配模式。

3 到 6 个字符且至少包含一个数字:

  1. let pwd = 'abc123'
  2. let reg = /(?=\w{3,6})(?=\D*\d)/
  3. reg.test(pwd)

匹配至少5个字符且有两个连续数字的密码:

  1. let sampleWord = "astronaut";
  2. let pwRegex = /(?=\w{5,})(?=\D*\d\d)/; //
  3. let result = pwRegex.test(sampleWords); //Returns true

反向引用

简单说就是在一个正则表达式中引用一个分组的子表达式。举个 HTML 标签的例子,如果要匹配 <h1></h1> 标签,可以这么写/<(h[1-6])>[\s\S]*<\/\1>/。这个正则可以匹配任意合法的 h 标签,其中 \1 就代表第 1 个分组的反向引用,否则就得为 h1 ~ h6 各写一个表达式就很累赘。反向引用的关键在于前面要先有分组,否则 \1 是无效的。

方法

match
replace
test
search

匹配 1-99 正则表达式

  1. /[1-9][0-9]?/

ip 正则表达式

  1. /^(192\.168(\.(\d|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))){2})$/

子网掩码正则表达式

  1. /^(254|252|248|240|224|192|128|0)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)$/

默认网关正则表达式

  1. /^(192\.168(\.(\d|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))){2})$/

首选 DNS 服务器和备选 DNS 服务器

  1. /(^(22[0-3]|2[0-1][0-9]|[0-1][0-9][0-9]|0[1-9][0-9]|([0-9])]{1,2}|[1-9][0-9]?)([.]([1-9][0-9]?|25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|0[1-9][0-9]|([0-9])]{1,2})){3})$/