正则表达式的两种模式
- 使用字符串方法
function pattern_repressenation(){
let pattern_string = "a\tb" ;// \t 匹配一个制表符。Tab
'a\\tb' ;// 特殊字符的时候需要 \ 进行转义
}
输出:a b
- 使用正则对象 regex —— /表达式/
let pattern_object = /a\tb/
pattern_object.source => /里面的内容/ a\tb
字符串方法
search(正则对象)
- 返回与正则表达式查找内容匹配的第一个子字符串的位置,没找到返回-1
// 字符串search (接收正则对象),用于检索与正则对象匹配的字符串
function string_search(){
let re = /\d+/ ;
// let re = '\\d+'
let text = 'my name is summer, I am 26 age!';
let outputText = ''
let idx = text.search(re)
}
match
- match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配
- 默认返回第一个值,没找到匹配的值返回null
function string_match(){
let re = /\d+/g
let text = '成都的邮政编码有:610000,610001,610002,610003'
let outputText = ''
let matches = text.match(re)
// 如果有多个匹配的话会返回一个数组 ["100000", "100010", "100032"]
// 如果只有一个返回的话返回第一个值
// 没有匹配的值返回null
if(match){
outputText = '\t 匹配值为' + matches
}else{
outputText = '\t 不匹配'
}
}
matchAll
- 返回一个包含所有匹配正则表达式及分组捕获结果的迭代器
- 需要全局g 修饰符
function string_matchAll(){
let re = /\d+/g
let text = '成都的邮政编码有:610000,610001,610002,610003'
let outputText = ''
let matches = text.matchAll(re);
for( let match of matches){
outputText += '\t匹配值:' + match[0] +'索引值'+ match.index+'<br>'
}
}
每一个match ,里面[0] 代表匹配的值,index:索引,input 原值字符串
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uMncxXim-1646203635946)(%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%20f63bfb905bbb44c2912118548f3c6a63/Untitled.png)]
分组
- 索引
function group_indexed(){
let re = /(\d{4})(\d{2})(\d{2})/g
let text = '今天的日期是:20210202'
let matches = text.matchAll(text)
let outputText = ''
for(let match of matches){
outputText += '分组[1]'+matche[1]+'\n' => 2021
outputText += '分组[2]'+matche[2]+'\n' => 02
outputText += '分组[3]'+matche[3]+'\n'=> 02
}
}
- 分组命名
function group_named(){
let re = /(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/g
let text = '今天的日期是:20210621'
let matches = text.matchAll(re)
let outputText = ''
for(let match of matches){
conosle.log(match) // ["20210621","2021","06","21"]
console.log(match.groups) // {"year":"2021","month":"06","day":"21"}
for(let i = 0;i<match.length;i++){
outputText += '分组['+i+']'+match[i]+'\n'
}
for(let p in match.groups){
outputText += '分组['+i+']'+match.groups[p]+'\n'
}
outputText += '分组[year]'+match.groups['year']+'\n' => 2021
outputText += '分组[month]'+match.groups['month']+'\n' => 06
outputText += '分组[day]'+match.groups['day']+'\n'=> 21
}
}
查找替换
- replace
- replace(re,第二个参数可以是回调函数或者字符串)
//替换
function find_replace(){
let re = /(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/g
let text = '今天的日期是:20210617,国庆放假时间:20211001'
let replace_pattern = '$<month>-$<day>-$<year>' // 要替换的格式 mm-dd-yyyy
let new_text = text.replace(re,replace_pattern)
//今天的日期是:06-17-2021,国庆放假时间:10-01-2021
}
// 格式化日期
match:匹配到的整个字符串,(匹配到几个满足正则表达式的就会调用几次)
offset: 匹配的索引位置
string : 初始字符串
groups:分组
function format_date(match,year,month,day,offset,string,groups){
let new_date = new Date(year,month,day)
return new_date.toDateString();
}
//替换-自定义
function find_replace_custom(){
let re = /(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/g
let text = '今天的日期是:20210617,国庆放假时间:20211001'
let new_text = text.replace(re,format_date)
}
//分割
function split(){
let re = /;/g
let text = 'a;b;c;d';
let new_text = text.split(re)
// ['a','b','c','d']
}
正则对象方法
- test() 方法
- 用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回true,否则返回false
function is_integer_regexp_test(text){
let re = /^\d+$/ // 必须是纯数字,限定了开头和结尾都是数字
let result = re.test(text)
return result
}
function integer_check_using_test(){
let text = 'abc123'
let check = is_integer_regexp_test(text)
}
- exec()
- 用于检索字符串中的正则表达式的匹配,该函数返回一个数组,其中存放匹配的结果。如果未找到匹配则返回值为null
- 当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
function re_exec(){
let re = /(?<year>\d{4})(?<month>\d{2})(?<day>\d{2})/g
let text = '今天的日期是:20210617,国庆放假时间:20211001'
let match
while((match = re.exec(text))){
for(let i =0;i<match.length;i++){
console.log(match[i])
}
// for(let value in match.groups){
//console.log(value)
//}
let {year,month,day} = match.groups
}
}
正则工具
- 菜鸟工具
正则表达式语法
- 简单的正则匹配
[ ] 字符集
let re = /[cfm]at/g // 以 c|f|m开头 结尾是at
量词
“*” 匹配0-N次
”+“ 匹配1-N次
?0次或1次
{n} 匹配n次
{n,} 匹配至少n次
{n,m} 最少匹配n次,最多m次
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0VaW7vph-1646203635948)(%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%20f63bfb905bbb44c2912118548f3c6a63/Untitled%201.png)]
元字符
\w 匹配字母、数字、下划线 等价于[A-Za-z0-9_]
\W 不匹配字母、数字、下划线
\d 十进制数字[0-9]
\D 匹配非数字字符
\s 匹配任何空白字符[\t\n\r\f\v]
\S 匹配任何非空白字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2YJDtofo-1646203635949)(%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%20f63bfb905bbb44c2912118548f3c6a63/Untitled%202.png)]
特殊字符
. 匹配任何字符除了\n \r
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zVKBsCfs-1646203635950)(%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%20f63bfb905bbb44c2912118548f3c6a63/Untitled%203.png)]
边界锚点
\b 边界区分(空格)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JdQ2J5Tj-1646203635951)(%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%20f63bfb905bbb44c2912118548f3c6a63/Untitled%204.png)]
选择字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ey0goKEa-1646203635952)(%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%20f63bfb905bbb44c2912118548f3c6a63/Untitled%205.png)]
用户名、邮箱、密码、手机号、生日匹配
// 正则表达式
const patterns = {
// 用户名要求5-8个英文或数字字符,i 忽略大小写
username:/^[a-z0-9]{5,8}$/i,
// 邮箱 必须是一个有效的邮箱地址,例如user@gmail.com
email:/^([a-z\d-]+)@([a-z\d-]+)\.([a-z]{2,8})(\.[a-z]{2,8})?$/,
// 密码 包含数字字母,可含特殊字符@,_- ,且长度再8-20之间
password:/^[\w@-]{8,20}$/,
// 中文名字
chineseName:/^[\u4e00-\u9fa5]{2,4}$/,
// 手机号
telphone:/^(13[0-9]|14[5-9]|15[0-9]|18[0-9]|19[1|3|8|9])\d{8}$/,
// 生日 不考虑2月
birth: /^((19[2-9]\d{1})|(20((0[0-9])|(1[0-9])|(2[0-1]))))\-((0?[1-9]|(1[0-2]))\-([0?(1-9])|([1-2][0-9]|30|31))$/
}
//验证函数
function validate(field,regex){
if(regex.test(field.value)){
field.className = 'valid'
}else{
field.className = 'invalid'
}
}
inputs.forEach((input)=>{
//事件监听
input.addEventListener('keyup',(e)=>{
validate(e.targe,patterns[e.target.attributes.name.value])
})
})
正则表达式的引擎
- 特征
- 正则引擎是通用的
- 遵循构建的正则模式指令
- 如果某条路径不匹配,可回溯选择其他路径
- 编写高效的正则表达式
- 分类
- DFA-确定型有穷自动机 : 可以确定字符匹配顺序
- NFA-非确定型有穷自动机: 不可以确定字符匹配顺序
DFA
- 由文本作为依据匹配,有顺序的,所有字符串只检查一次,从左往右查验
字符串 正则表达式
abc a(d|b)c
NFA
- 先看正则表达式,按表达式去匹配字符串
字符串 正则表达式
abc a(d|b)c
常用正则表达式
- 截取script标签的src的值
var reg3 = /<script.*?src="(.*?)".*?\/?>/i
const url = item.match(reg3)[1]
- 截取script标签内的innerText
var reg2 = /<script>([\s\S]*?)<\/script>/
let script = document.createElement('script')
- 截取字符串中以结尾的字符串
var reg = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi
var result = res.match(reg)
- 手机号中间展示****
mobileVal.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
- 正确的手机号
if (!/^1[3456789]\d{9}$/.test(this.mobileValBefore)){
Toast("请填写正确的手机号")
}