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:多行
let quit = "qu";
let noquit = "qt";
let quRegex= /q(?=u)/;
let qRegex = /q(?!u)/;
quit.match(quRegex); // Returns ["q"]
noquit.match(qRegex); // Returns ["q"]
先行断言
先行断言的语法形式为 /c(?=a)/
,表示匹配 a 左边的 c。为了避免与断言中的「前」和 「后」混淆,这里就用「a 左边的 c」来表达。
先行断言有些地方也叫「前瞻断言」或「前向查找」,想象你自己就是一个指针,扫描字符串的过程就像指针在向前移动。
先行断言也有其否定形式,叫做先行否定断言,如 /c(?!a)/
,即匹配「非a」左边的 c,其实这与 /c(?=[^a])/
效果相同
(?:pattern)
:表示匹配 pattern,但不获取匹配的子字符串
正向先行断言(?=...)
:...
表示需要存在但不会被匹配到的部分
负向先行断言(?!...)
:...
表示希望不存在的匹配模式
更实际的用途:检查一个字符串的两个或更多匹配模式。
3 到 6 个字符且至少包含一个数字:
let pwd = 'abc123'
let reg = /(?=\w{3,6})(?=\D*\d)/
reg.test(pwd)
匹配至少5个字符且有两个连续数字的密码:
let sampleWord = "astronaut";
let pwRegex = /(?=\w{5,})(?=\D*\d\d)/; //
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-9][0-9]?/
ip 正则表达式
/^(192\.168(\.(\d|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))){2})$/
子网掩码正则表达式
/^(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)$/
默认网关正则表达式
/^(192\.168(\.(\d|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))){2})$/
首选 DNS 服务器和备选 DNS 服务器
/(^(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})$/