- 简写
字符组第一位放^表示求反
- \d 表示[0-9]
- \D 表示[^0-9]
- \w 表示[0-9a-zA-Z_]
- \W 表示[^0-9a-zA-Z_]
- \s 表示[\t\v\n\r\f]
- \S 表示[^\t\v\n\r\f]
- . 表示[^\n\r\u2028\u2029]
匹配任意字符可以使用[\d\D]、[\w\W]、[\s\S]、[^]
-
量词
贪婪量词 | 惰性量词
—|—
{m,n} | {m,n}?
{m,} | {m,}?
{m} | {m}?
? | ??
+
| +?
*
| *? -
分支
分支结构也是惰性的
'goodbye'.match(/good|goodbye/)
//output: 'good'
- 位置
^
$
\b:\w与\W之间,\w与^之间,\w与KaTeX parse error: Undefined control sequence: \B at position 8: 之间 \̲B̲:\w与\w之间,\W与\W之…之间
(?=p):正向先行断言,匹配p前面的位置
(?!p):负向先行断言,匹配除p前面的位置的其他位置(加g,否则只匹配第一个位置) - 反向引用
var reg = /\d{4}([./-])\d{2}\1\d{2}/
\1 表示第一个子表达式匹配到的值
\2 表示第二个子表达式匹配到的值
…
\10 表示第十个子表达式匹配到的值
要匹配\10使用 (?:\1)0 或者 \1(?:0) - 非捕获括号
之前的括号子表达式都会捕获他们匹配的数据(反向引用),以便后续使用
非捕获括号就是在前面增加?:
var regex = /^I love (?:JavaScript|Regular Expression)$/
- 正则表达式回溯法原理
- 效率
- 使用具体型字符组来代替通配符,来消除回溯
- 使用非捕获型分组
- 独立出确定字符(加快匹配速度)
- 提取分支公共部分(可减少匹配过程中可消除的重复)
- 减少分支的数量
- js提供的正则方式
- search
var reg = /[a-zA-Z]/
var str = '123a'
!!~str.search(reg)
//output: true
- 提取match / matchAll
const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
str.match(regexp) // output: [test1,test2]
//ES2020新增新增matchAll方法匹配详细信息
const matchs = str.matchAll(regexp);
console.log(matchs); // RegExpStringIterator {}
console.log([...matchs]) //类数组需要转换为数组
//output: [["test1", "e", "st1", "1", index: 0, input: "test1test2", groups: undefined],["test2", "e", "st2", "2", index: 5, input: "test1test2", groups: undefined]]
- 替换replace
str.replace(reg,'a')
- 匹配test
reg.test(str)
- 提取exec
const regexp = RegExp('foo[a-z]*','g');
const str = 'table football, foosball';
regexp.exec(str) // output: exec仅支持匹配一条,如果需要匹配多条建议使用matchAll
- replace是很强大的,当第二个参数是字符串时,以下字符有特殊含义
属性 | 描述 |
---|---|
$1,$2,…,$99 | 匹配第1到99个分组里捕获的文本 |
$& | 匹配到的字串文本 |
$` | 匹配到子串的左边文本 |
$’ | 匹配到子串的右边文本 |
$$ | 美元符号 |
"2+3=5".replace(/=/, "$&$`$&$'$&")
output: "2+3=2+3=5=5"
- 构造函数属性
静态属性 | 描述 | 简写形式 |
---|---|---|
RegExp.input | 最近一次目标字符串 | RegExp[“$_”] |
RegExp.lastMatch | 最近一次匹配的文本 | RegExp[“$&”] |
RegExp.lastParen | 最近一次捕获的文本 | RegExp[“$+”] |
RegExp.leftContext | 目标字符串中lastMatch之前的文本 | RegExp[“$`”] |
RegExp.rightContext | 目标字符串中lastMatch之后的文本 | RegExp[“$'”] |
作业练习
- 要求匹配颜色
#ffbbad
#Fc01DF
#FFF
#ffE
结果为:
/#([0-9a-zA-Z]{3}|[0-9a-zA-Z]{6})/
- 要求匹配时间
23:59
02:07
结果为:
^(((0|1)\d)|2[0-3]):[0-5]\d$
如果前面的0可以省略
结果为:
^(0?\d|1\d|2[0-3]):(0?\d|[1-5]\d)$
- 匹配日期
2018-12-25
/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/
对于2018-01-05兼容简写形式18-1-5
/^(\d{4}|\d{2})-(0?[1-9]|1[0-2])-(0?[1-9]|[12]\d|3[01])$/
- 匹配路径
“F:\study\javascript\regex\regular expression.pdf”
“F:\study\javascript\regex\”
“F:\study\javascript”
“F:\”
/^[a-zA-Z]:\\([^\n\r?:\\/*"<>|]+\\)*[^\n\r?:\\/*"<>|]*$/
- 匹配id
‘ ’
/id=".*"/
//output:'id="container" class="main"'
原因:*量词默认是贪婪匹配,所以增加?变为惰性匹配
/id=".*?"/
//output:'id="container"'
- 不匹配任何字符
/.^/或者/$./
- 数字的千位分隔符
匹配’123456789’
/(?!^)(?=(\d{3})+$)/g
output:'123,456,789'
匹配’1234 5678 912 345 6789’
/(?!\b)(?=(\d{3})+\b)/g
output: '1,234 5,678 912 345 6,789'
(?!\b) = \B 所以可以变换为
/\B(?=(\d{3})+\b)/g
- 货币格式化
var num = 1880
var reg1 = /(?!^)(?=(\d{3})+$)/g
var reg2 = /^/
num.toFixed(2).replace(reg1,',').replace(reg2,'$ ')
// output:$ 1,880.00
- 验证密码
密码长度6-12位,由数字、小写字母、大写字母组成,但必须至少包含2种字符
方法1:
step1:匹配数字、小写字母、大写字母
/^[0-9A-Za-z]{6,12}$/
step2:必须包含数字
/(?=.*[0-9])^[0-9A-Za-z]{6,12}$/
step3:必须包含任意两种
/((?=.*[0-9])(?=.*[a-z])|(?=.*[A-Z])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z]))^[0-9A-Za-z]{6,12}$/
方法2:
/(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/
- 字符串trim方法模拟
/^\s+|\s+$/g
或者
/^\s*(.*?)\s*$/g
这里使用?惰性匹配防止匹配到最后一个空字符串之前的空字符串
11. 每个单词的首字母替换为大写
/(?:^|\s)\w/g
这里也可以不使用非捕获
12. 驼峰法
/[\s_-]+(.)?/g
- 匹配成对标签
var str = '<span>lulin</span>'
var reg = /<([^]+)>[\d\D]*<\/\1>/
- 身份证
/^(\d{15}|\d{17}[\dxX])$/
- IPV4
/^((0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(0{0,2}\d|0?\d{2}|1\d{2}|2[0-4]\d|25[0-5])$/