js正则表达式之捕获

1、基于exec的捕获

/**
 * 1、基于exec的捕获
 *    1.捕获到的结果是null或者是一个数组
 *     1).第一项是本次捕获到的内容
 *     2).第二项是index 表示当前捕获到的字符串在整个字符串中的索引位置
 *     3).第三项是 input 原始字符串
 * 2、每执行一次,我们就会获取到一个符合正则规则的结果,但是默认情况(懒惰)下我们就算执行100遍也只会获取到第一个匹配到的结果
 */
 let str = "dd231hj1312h31j2b3j12k31j2b31j2";

let reg = /\d+/;
let result = reg.exec(str);
console.log("result:", result, result[0]); // => [ '231',index: 2, input: 'dd231hj1312h31j2b3j12k31j2b31j2', groups: undefined ] '231'

lastIndex:当前正则下一次匹配的起始索引位置

/**
 * reg.lastIndex
 * 当前正则下一次匹配的起始索引位置
 */
let str = "das131hj123hjk";
let reg = /\d+/g;
// 当正则设置全局匹配修饰符g之后,lastIndex会自动的修改到新的索引起始位置
console.log(reg.lastIndex); // => 0

console.log(reg.exec(str)); // => ['131',...]
console.log(reg.lastIndex); // => 6  下一次从索引为6的地方开始匹配

console.log(reg.exec(str)); // => ['123',...] 第二次捕获,捕获到123
console.log(reg.lastIndex); // => 11  下一次从索引为11的地方开始匹配

// 没有匹配到结果后,会返回null , 但是lastIndex又会变为0,再次捕获又会从第一个开始捕获
console.log(reg.exec(str)); // => null 没有捕获到东西
console.log(reg.lastIndex); // => 0

注意: 正则的懒惰性:默认情况下lastIndex的值是不会修改的,每一次都是从字符串的开始位置进行查找,所以找到的永远是第一个
解决懒惰性 => 添加全局修饰符:g

自定义一个exec的全部捕获方法

/**
 * 为了解决exec只能捕获一次,我们可以编写一个函数来一次性把所有的结果都捕获到
 * 前提:正则必须设置全局修饰符 g
 */
function execAll(str) {
  // str => 要捕获的字符串
  // 一进来要先判断当前正则是否有全局修饰符参数,没有设置就不能进行循环捕获了,不然会导致死循环
  if (!this.global) {
    // 如果没有全局修饰符
    return this.exec(str);
  }
  let arr = [],
    res = this.exec(str);
  while (res) {
    arr.push(res[0]);
    // 只要捕获结果不为null,那么就继续捕获下去
    res = this.exec(str);
  }
  return arr;
}
RegExp.prototype.execAll = execAll;
let text = "123h34hj23k123jk234";
let reg3 = /\d+/g;
console.log("reg3", reg3.execAll(text)); // => [ '123', '34', '23', '123', '234' ]

也可以使用match来进行全部匹配

正则捕获的贪婪性

/**
 * 正则捕获的贪婪性
 * 默认情况下,正则是按照当前所能匹配的最长的结果来进行获取的,当设置了+ 和 * 时
 */
let text = "sda1231k121h231h21l123j2";
let reg = /\d+/g;
console.log(text.match(reg)); // => [ '1231', '121', '231', '21', '123', '2' ]
// 在量词元字符后面设置了 ? => 取消捕获时的贪婪性(按照正则匹配的最短结果来获取)
let reg2 = /\d+?/g;
console.log(text.match(reg2)); //[ '1','2','3','1','1','2','1',... ]
  • 在正则中 ? 的作用
  • 问号左边是非量词元字符:本身代表量词元字符,出现零到一次
  • 问号左边是量词元字符:取消捕获时候的贪婪性
  • (?:) 只匹配,不捕获
  • (?=) 正向查找
  • (?!) 负向查找

test捕获

// 其它捕获方式 test => 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 存储的是上一次捕获的值

replace方法使用

// replace方法
/**
 * 1、使用replace方法处理时间字符串
 */
let time = "2020-12-23";
// 变为2020年12月23日
let reg = /^(\d{4})-(\d{1,2})-(\d{1,2})$/;
// let newTime = time.replace(reg, "$1年$2月$3日");
// console.log(newTime); // => 2020年12月23日

// 还可以这么处理 time.replace(reg,[function])
// 这样子首先会把reg和time来进行匹配,匹配几次后面的回调函数就会执行几次
time = time.replace(reg, function (str, $1, $2, $3) {
  console.log($1, $2, $3); // => 2020 12 23
});

replace方法练习:

//replace 方法练习 => 让英文首字母大写
let english = "hello world, my name is jerry";
let reg2 = /\b([a-zA-Z])[a-zA-Z]*\b/g; // => \b 用来匹配单词的边界
// 回调函数会执行六次,每一次都会把捕获到的结果传递给函数
english = english.replace(reg2, function (...arg) {
  let [content, $1] = arg;
  $1 = $1.toUpperCase();
  content = content.substring(1);
  return $1 + content;
});
console.log(english); // => Hello World, My Name Is Jerry
/**
 * js正则中\b的用法
 * \b用来匹配单词的边界,即\w和\W之间的位置,或字符串首位与\w或\w与字符串末尾的位置。
 */
let str = "aa bb cc dd";
let reg3 = /\b\w+\b/g;
console.log(reg3.exec(str)); //aa
console.log(reg3.exec(str)); //bb
console.log(reg3.exec(str)); //cc
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值