正则捕获的贪婪性
let str = "ssdfdfg2019mjlkh2020sdfsdf";
// => 正则捕获的贪婪性: 默认情况下,正则捕获的时候, 是按照当前正则匹配的最长结果来获取的
let reg = /\d+/g;
console.log(str.match(reg)); // => ["2019", "2020"], 因为贪婪性,所以没有得出["2","0","1"....]这个结果
//在量词元字符后边添加?:取消捕获时的贪婪性(按照正则匹配的最短结果来获取)
reg = /\d+?/g;
console.log(str.match(reg)); // => ["2", "0", "1", "9", "2", "0", "2", "0"]
- 问号的5个作用
- 1.问号左边是非量词元字符: ?本身代表量词元字符, 出现零到一次
- 问号左边是量词元字符: 取消捕获时的贪婪性,按照最短匹配结果来进行
- (?:) 只匹配,不捕获
- (?=) 正向预查
- (?!) 负向预查
其他正则捕获的方法
-
1.test也能捕获(本意是匹配)
let str = "{0}年{1}月{2}日"; let reg = /\{(\d+)\}/g; console.log(reg.test(str)); // => true console.log(RegExp.$1) // => "0" console.log(reg.test(str)); // => true console.log(RegExp.$1) // => "1" console.log(reg.test(str)); // => true console.log(RegExp.$1) // => "2" console.log(reg.test(str)); // => false console.log(RegExp.$1) // => "2" (存储的是上一次捕获的结果) // RegExp.$1~RegExp.$9: 获取当前本次正则匹配后,第一个到第九个分组的信息 // 分组index默认从1开始,这点和数组不一样
-
2.replace---字符串中实现替换的方法(一般都是伴随正则一起使用的)
let str = "qianduan@2019|qianduan@2020"; // => 把“qianduan”替换成“前端” str = str.replace("qianduan", "前端"); console.log(str); // 前端@2019|qianduan@2020, 每次只能替换一个,执行多次才能完成 // 2.使用正则可以做到全局匹配,替换 str = str.replace(/qianduan/g, "前端"); console.log(str); // 前端@2019|前端@2020, 一次搞定
有些需求必须使用正则
let str = "qianduan@2019|qianduan@2020"; // 需求:把qianduan替换为qianduanxuexi str = str.replace("qianduan", "qianduanxuexi") console.log(str); //qianduanxuexi@2019|qianduan@2020 // 还差一步。再来一次 str = str.replace("qianduan", "qianduanxuexi") console.log(str); //qianduanxuexixuexi@2019|qianduan@2020 // 出了点问题,str不会区分上次匹配的结束位置,每次都是从0开始 // 使用正则 str = str.replace(/qianduan/g, "qianduanxuexi") console.log(str); //qianduanxuexi@2019|qianduanxuexi@2020
-
案例: 处理时间字符串
let time = "2019-10-13"; // => 变为 “2019年10月13日” let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/; // 这样可以实现 time = time.replace(reg, "$1年$2月$3日"); console.log(time); // => 2019年10月13日 // 还可以这样处理: str.replace(reg, fn) /* * 1.首先拿reg和time进行匹配捕获, 能匹配几次就会把传递的函数(上边的fn)执行几次(而且是匹配一次就执行一次) * 2.不仅把方法执行,而且replace还给方法传递了实参信息(和exec捕获的内容一致的信息: 大正则匹配的内容,小分组匹配的信息) * 3.在函数中我们返回的是什么,就把当前大正则匹配的内容替换成什么 */ time = time.replace(reg, (big,$1,$2,$3) => { // 参数:大正则,三个小分组 // 这里的$1~$3使我们自己设置的变量 console.log(big,$1,$2,$3); }) // 或者 time = time.replace(reg, (...args) => { // 参数:大正则,三个小分组 // 这里的$1~$3使我们自己设置的变量 let[,$1,$2,$3] = args; console.log($1,$2,$3); $2.length<2 ? $2="0"+$2 : null; $3.length<2 ? $3="0"+$3 : null; return $1+"年"+$2+"月"+$3+"日"; }) // time => "2019年10月13日" // 从fn函数的参数,可以得出结论,replace也可以捕获
-
单词首字母大写
let str = "good good study, day day up!" let reg = /\b([a-zA-Z])[a-zA-Z]*\b/g; // 因为有6个单词,所以捕获6次,即fn要执行6次,每一次都把正则匹配信息传递给函数 str = str.replace(reg, (...args) => { let [big, a] = args; return a.toUpperCase()+big.slice(1); })
-
验证一个字符串中哪个字母出现的次数最多,多少次?
let str = "haohaoxuexitiantianxiangshang"; /* * 方法一:将str格式化为一个对象{a:10,,b:5,c:3,...},然后各种排序->获得结果(不多赘述) * 方法二:格式化str,将相同字母合在一起,利用上一节分组捕获分别获取每个小分组,然后计算 */ let formatStr = str.split("").sort((a, b) => a.localeCompare(b)).join(""); console.log(formatStr); // aaaaaaegghhhiiiinnnnoosttuxxx let reg = /([a-zA-Z])\1+/g; let ary = formatStr.match(reg); // => ["aaaaaa", "gg", "hhh", "iiii", "nnnn", "oo", "tt", "xxx"] ary.sort((a, b) => b.length-a.length) // => ["aaaaaa", "iiii", "nnnn", "hhh", "xxx", "gg", "oo", "tt"] let max = ary[0].length; let maxAry = []; ary.forEach((str) => { if(str.length === max) maxAry.push(str[0]) }) console.log(maxAry) // ["a"] console.log(`出现次数最多的字符是: ${maxAry},出现的次数是${max}`) /* * 方法三: 与方法二前置内容一样,先把str以相同字母排序成一个新的str,然后以这个字符串为基准,一次递减,判断最长子串 */ let str = "haohaoxuexitiantianxiangshang"; let max = 0, res = [], flag = false; let formatStr = str.split("").sort((a, b) => a.localeCompare(b)).join(""); for(let i=str.length;i>0;i--) { let reg = new RegExp("([a-zA-Z])\\1{"+(i-1)+"}","g") str.replace(reg, (content, $1) => { res.push($1); max = i; flag = true; }) if(flag) break; } /* * 方法四: 从字符串中拿出一项,用这个单一字母正则匹配这个长字符串,并且替换为空,判断前后大字符串长度差值,也可得出结果 */ let str = "zhufengpeixundezhengzekechengzhendefeichangbucuo"; let arr = []; let max = 0; let reg = null; let letter = ""; let newStr = ""; let distance = 0; let oldLen = 0; while (str.length > 0) { oldLen = str.length; letter = str.slice(0, 1); // if(letter != "d" && letter != "n" && letter != "w") reg = new RegExp(letter, "g"); str = str.replace(reg, ""); distance = oldLen - str.length; if (distance > max) { arr = [letter]; } else if (distance === max) { arr.push(letter); } max = distance > max ? distance : max; }
-
网友评论