JS正则表达式

简介

正则表达式是用于匹配字符串中字符组合的模式,在 JavaScript中,正则表达式也是对象。与普通函数操作字符串来比较,正则表达式可以写出更简洁、功能强大的代码。

引入
  • 下面使用获取字符串中的所有数字来比较函数与正则的差异。
let jose = "wang2200cms9988";
let nums = [...hd].filter(a => !Number.isNaN(parseInt(a)));
console.log(nums.join(""));
// 使用正则表达式将简单得多
let jose = "wang2200cms9988";
console.log(hd.match(/\d/g).join(""));
1.创建正则

JS提供字面量与对象两种方式创建正则表达式

  1. 字面量创建
    – 使用//包裹的字面量创建方式是推荐的作法,但它不能在其中使用变量
let jose = "wangxiaoyu";
console.log(/u/.test(jose));//true
  1. 下面尝试使用 a 变量时将不可以查询
let jose = "wangxiaoyu";
let a1 = "u";
console.log(/a1/.test(jose)); // false

虽然可以使用 eval 转换为js语法来实现将变量解析到正则中,但是比较麻烦,所以有变量时建议使用下面的对象创建方式

let jose = "wangxiaoyu";
let a1 = "u";
console.log(eval(`/${a1}/`).test(jose)); //true
  1. 对象创建
    – 当正则需要动态创建时使用对象方式
const content = prompt('请输入要搜索的内容,支持正则表达式')
let reg = new RegExp(content, 'g')
let body = document.querySelector('#content').innerHTML.replace(reg, str => {
    return `<span style='color:red'>${str}</span>`
})
document.body.innerHTML = body

提取某标签内容

// 以下三种结果一样的输出结果 
let body = document.getElementById('content').innerHTML
const res = body.match(/<(span)>.+<\/\1>/g)
const res2 = body.match(/<(span)>.+<\/span>/g)
const res3 = body.match(/<span>.+<\/span>/g)
console.log('res: ', res)
console.log('res2: ', res2)
console.log('res3: ', res3)
2.选择符 |

|这个符号带表选择修释符,也就是 | 左右两侧有一个匹配到就可以。

let jose = 'wangxiaoyu.com'
console.log(/wang|com/.test(jose)) // false

let tel = "010-12345678";
//错误结果:只匹配 | 左右两边任一结果
console.log(tel.match(/010|020\-\d{7,8}/)); 

//正确结果:所以需要放在原子组中使用
console.log(tel.match(/(010|020)\-\d{7,8}/));
3.原子表和原子组
const res1 = /[1,2,3,4,5]/ // 原子表
const res2 = /(11|33)/ // 原子组---按组匹配
let jose = 'wangxiaoyu.com1133'
console.log(jose.match(res1)) // true
console.log(jose.match(res2)) // true
4.字符转义

转义用于改变字符的含义,用来对某个字符有多种语义时的处理。

假如有这样的场景,如果我们想通过正则查找/符号,但是 /在正则中有特殊的意义。如果写成///这会造成解析错误,所以要使用转义语法 /\//来匹配。

let jose = 'https://wangxiaoyu.com'
// 使用 RegExp 构建正则时在转义上会有些区别
let reg = new RegExp('https:\\/\\/')  
console.log(/https:\/\//.test(jose)) // true
console.log(reg.test(jose)) // true
5.字符边界限定
边界符说明
^匹配字符串的开始
$匹配字符串的结束,忽略换行符

// 数字开头,数字结尾
let jose = '1https://wangxiaoyu.com1'
console.log(/^\d.*\d$/.test(jose)) // true
  • 检测用户名长度为3~6位,且只能为字母。如果不使用 ^与$ 限制将得不到正确结果
<body>
  <input type="text" name="username" />
</body>

<script>
  document
    .querySelector(`[name="username"]`)
    .addEventListener("keyup", function() {
    // 检测用户名长度为3~6位
      let res = this.value.match(/^[a-z]{3,6}$/i);
      console.log(res);
      console.log(res ? "正确" : "失败");
    });
</script>
6.元子字符

元字符是正则表达式中的最小元素,只代表单一(一个)字符

元字符说明示例
\d匹配任意一个数字[0-9]
\D与除了数字以外的任何一个字符匹配[^0-9]
\w与任意一个英文字母,数字或下划线匹配[a-zA-Z_]
\W除了字母,数字或下划线外与任何字符匹配[^a-zA-Z_]
\s任意一个空白字符匹配,如空格,制表符\t,换行符\n[\n\f\r\t\v]
\S除了空白符外任意一个字符匹配[^\n\f\r\t\v]
.匹配除换行符外的任意字符
使用体验
  1. 匹配任意数字
let jose = 'https://wangxiaoyu.com1010'
console.log(jose.match(/\d\d\d\d/)) 
  1. 匹配所有电话号码
let jose = `张三:010-99999999,李四:020-88888888`
console.log(jose.match(/\d{3}\-\d{8}/g))
  1. 匹配任意非数字
console.log(/\D/.test(2029)); //false 
  1. 匹配字母数字下划线
let jose = "hdcms@";
console.log(jose.match(/\w/g));  
  1. 匹配除了字母,数字或下划线外与任何字符匹配
console.log(/\W/.test("@")); //true
  1. 匹配与任意一个空白字符匹配
console.log(/\s/.test(" ")); //true
console.log(/\s/.test("\n")); //true
  1. 使用.匹配除换行符外任意字符,下面匹配不到wang.com 因为有换行符
let jose = `
  <span>
    houdunren
    hdcms
  </span>
`;
let res = jose.match(/<span>.*<\/span>/s);
console.log(res[0]);
  1. 正则中空格会按普通字符对待
let tel = `010 - 999999`;
console.log(/\d+-\d+/.test(tel)); //false
console.log(/\d+ - \d+/.test(tel)); //true
  1. 所有字符
    可以使用 [\s\S] 或 [\d\D] 来匹配所有字符
let jose = `
  <span>
    wang
    jose
  </span>
`;
let res = jose.match(/<span>[\s\S]+<\/span>/);
console.log(res[0]);
7. 模式修饰符
修饰符说明
i不区分大小写字母的匹配
g全局搜索所有匹配内容
m视为多行
s视为单行忽略换行符,使用. 可以匹配所有字符
y从 regexp.lastIndex 开始匹配
u正确处理四个字符的 UTF-16 编码
  1. i / g
let jose = 'wangjoseA'
console.log(jose.match(/a/gi))
  1. m
    用于将内容视为多行匹配,主要是对 ^和 $ 的修饰

将下面是将以 #数字开始的课程解析为对象结构,学习过后面讲到的原子组可以让代码简单些

letjose = `
            #1 js,200元 #
            #2 php,300元 #
            #9 houdunren.com # 后盾人
            #3 node.js,180元 #
            `
// [{name:'js',price:'200元'}]
let lessons = jose.match(/^\s*#\d+\s+.+\s+#$/gm).map(v => {
    v = v.replace(/\s*#\d+\s*/, '').replace(/\s+#/, '')
    ;[name, price] = v.split(',')
    return { name, price }
})
console.log(JSON.stringify(lessons, null, 2))

在这里插入图片描述
2. u
每个字符都有属性,如L属性表示是字母,P 表示标点符号,需要结合 u 模式才有效。其他属性简写可以访问 属性的别名 网站查看。

//使用\p{L}属性匹配字母
let jose = 'houdunren2010.不断发布教程,加油!'
console.log(jose.match(/\p{L}+/u))

//使用\p{P}属性匹配标点
console.log(jose.match(/\p{P}+/gu))

字符也有unicode文字系统属性 Script=文字系统,下面是使用 \p{sc=Han} 获取中文字符 han为中文系统,其他语言请查看 文字语言表

// 匹配中文
let jose = `张三:010-99999999,李四:020-88888888`
let res = jose.match(/\p{sc=Han}+/gu)
console.log(res)

使用 u 模式可以正确处理四个字符的 UTF-16 字节编码

let jose = "𝒳𝒴";
console.table(jose.match(/[𝒳𝒴]/)); //结果为乱字符"�"

console.table(jose.match(/[𝒳𝒴]/u)); //结果正确 "𝒳"
  1. y
    我们来对比使用 y 与g 模式,使用 g 模式会一直匹配字符串
let jose = 'wang'
let reg = /a/g
console.log(reg.exec(jose))
console.log(reg.lastIndex) //2
console.log(reg.exec(jose))
console.log(reg.lastIndex) //0
console.log(reg.exec(jose)) //null
console.log(reg.lastIndex) //2

但使用y 模式后如果从 lastIndex 开始匹配不成功就不继续匹配了

let jose = 'wang'
let reg = /w/y
console.log(reg.exec(jose))
console.log(reg.lastIndex) //1
console.log(reg.exec(jose)) //null

因为使用 y 模式可以在匹配不到时停止匹配,在匹配下面字符中的qq时可以提高匹配效率

let jose = `QQ群:11111111,999999999,88888888xx.com`
let reg = /(\d+),?/y
reg.lastIndex = 4
while ((res = reg.exec(jose))) console.log(res[1])
8. lastIndex

RegExp对象lastIndex 属性可以返回或者设置正则表达式开始匹配的位置

  • 必须结合 g 修饰符使用
  • 对 exec 方法有效
  • 匹配完成时,lastIndex 会被重置为0
let jose = `时间就像海绵里的水`
let reg = //g
reg.lastIndex = 0 //从索引10开始搜索
console.log(reg.exec(jose))
console.log(reg.lastIndex)

reg = /\p{sc=Han}/gu
while ((res = reg.exec(jose))) {
    console.log(res[0])
}
9.原子表

在一组字符中匹配某个元字符,在正则表达式中通过元字符表来完成,就是放到[] (方括号)中。

使用语法

原子表说明
[]只匹配其中的一个原子
[^]只匹配"除了"其中字符的任意一个原子
[0-9]匹配0-9任何一个数字
[a-z]匹配小写a-z任何一个字母
[A-Z]匹配大写A-Z任何一个字母

实例操作
使用[]匹配其中任意字符即成功,下例中匹配os任何一个字符,而不会当成一个整体来对待

let jose = `josewang`
console.log(jose.match(/[os]/g)) //['o', 's']

日期的匹配

let tel = '2022/02/23'
console.log(tel.match(/\d{4}([-\/])\d{2}\1\d{2}/))

获取0~3间的任意数字

 const num = '2'
 console.log(/[0-3]/.test(num)) //true
 // 顺序为升序否则将报错
 const num = "2";
 console.log(/[3-0]/.test(num)); //SyntaxError

匹配a~f间的任意字符

const jose = "e";
console.log(/[a-f]/.test(jose)); //true
// 顺序为升序否则将报错
const jose = "houdunren.com";
console.log(/[f-a]/.test(jose)); //SyntaxError

获取所有用户名

let jose = `张三:010-99999999,李四:020-88888888`
let res = jose.match(/[^:\d-,]+/g)
console.log(res)

原子表中有些正则字符不需要转义,如果转义也是没问题的,可以理解为在原子表中. 就是小数点

let str = '(josewang.com).+'
console.table(str.match(/[().+]/g))

//使用转义也没有问题
console.table(str.match(/[\(\)\.\+]/g))

可以使用 [\s\S] 或 [\d\D]匹配到所有字符包括换行符

const reg = /[\s\S]+/g;

下面是使用原子表知识删除所有标题

<body>
  <p>jose</p>
  <h1>josewang.com</h1>
  <h2>jose.com</h2>
</body>
<script>
  const body = document.body;
  const reg = /<(h[1-6])>[\s\S]*<\/\1>*/g;
  let content = body.innerHTML.replace(reg, "");
  document.body.innerHTML = content;
</script>
10.原子组
  • 如果一次要匹配多个元子,可以通过元子组完成
  • 原子组与原子表的差别在于原子组一次匹配多个元子,而原子表则是匹配任意一个字符
  • 元字符组用 () 包裹
    基本使用
    没有添加 g 模式修正符时只匹配到第一个,匹配到的信息包含以下数据
变量说明
0匹配到的完整内容
1,2…匹配到的原子组
index原字符串中的位置
input原字符串
groups命名分组

在match中使用原子组匹配,会将每个组数据返回到结果中

  • 0 为匹配到的完成内容
  • 1/2 等 为原子级内容
  • index 匹配的开始位置
  • input 原始数据
  • groups 组别名

下面使用原子组匹配标题元素

let jose= `
        <h1>wang</h1>
        <span>jose</span>
        <h2>jose</h2>
        `
console.table(jose.match(/<(h[1-6])[\s\S]*<\/\1>/g))

邮箱匹配

let jose = '2300071698@qq.com'
let reg = /^[\w\-]+@[\w\-]+\.(com|org|cn|cc|net)$/i
console.dir(jose.match(reg))

// 如果邮箱是以下格式 houdunren@jose.com.cn 上面规则将无效,需要定义以下方式
let jose = `admin@wang.com.cn`
let reg = /^[\w-]+@([\w-]+\.)+(org|com|cc|cn)$/
console.log(jose.match(reg))
11.引用分组

\n 在匹配时引用原子组, $n 指在替换时使用匹配的组数据。下面将标签替换为p标签

let jose = `
        <h1>wang</h1>
        <span>yyy</span>
        <h2>jose</h2>
        `
let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi
console.log(jose.replace(reg, `<p>$2</p>`))
12.不记录分组

如果只希望组参与匹配,便不希望返回到结果中使用 (?: 处理。下面是获取所有域名的示例

letjose = `
        https://www.ha.com
        http://as.com
        https://sd.com
        `

let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|org|cn))/gi
while ((v = reg.exec(jose))) {
    console.dir(v)
}

分组别名
组别名使用 ?<> 形式定义,下面将标签替换为p标签

let hd = `
  <h1>jose</h1>
  <span>王</span>
  <h2>wang</h2>
`;
let reg = /<(?<tag>h[1-6])>(?<con>[\s\S]*)<\/\1>/gi;
console.log(hd.replace(reg, `<p>$<con></p>`));

获取链接与网站名称组成数组集合

<body>
  <a href="https://www.jose.com">后盾人</a>
  <a href="https://www.wang.com">hdcms</a>
  <a href="https://www.sina.com.cn">新浪</a>
</body>

<script>
  let body = document.body.innerHTML;
  let reg = /<a\s*.+?(?<link>https?:\/\/(\w+\.)+(com|org|cc|cn)).*>(?<title>.+)<\/a>/gi;
  const links = [];
  for (const iterator of body.matchAll(reg)) {
    links.push(iterator["groups"]);
  }
  console.log(links);
</script>
13. 重复匹配

如果要重复匹配一些内容时我们要使用重复匹配修饰符,包括以下几种。

符号说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

因为正则最小单位是元字符,而我们很少只匹配一个元字符如a、b所以基本上重复匹配在每条正则语句中都是必用到的内容

默认情况下重复选项对单个字符进行重复匹配,即不是贪婪匹配

 let jose = 'joseeeeeeee'
 console.log(jose.match(/jose+/i)) //joseeeeeeee
  • 使用原子组后则对整个组重复匹配

let jose = 'joseeeeeeee'
console.log(jose.match(/(jose)+/i)) //jose
  • 下面是验证坐机号的正则
let jose = "010-12345678";
console.log(/0\d{2,3}-\d{7,8}/.exec(jose));
  • 验证密码必须包含大写字母并在5~10位之间
let input = document.querySelector(`[name="password"]`)
input.addEventListener('keyup', e => {
    const value = e.target.value.trim()
    const regs = [/^[a-zA-Z0-9]{5,10}$/, /[A-Z]/]
    let state = regs.every(v => v.test(value))
    console.log(state ? '正确!' : '密码必须包含大写字母并在5~10位之间')
})
14.禁止贪婪

正则表达式在进行重复匹配时,默认是贪婪匹配模式,也就是说会尽量匹配更多内容,但是有的时候我们并不希望他匹配更多内容,这时可以通过?进行修饰来禁止重复匹配

使用说明
*?重复任意次,但尽可能少重复
+?重复1次或更多次,但尽可能少重复
??重复0次或1次,但尽可能少重复
{n,m}?重复n到m次,但尽可能少重复
{n,}?重复n次以上,但尽可能少重复

下面是禁止贪婪的语法例子

let str = "aaa";
console.log(str.match(/a+/)); //aaa
console.log(str.match(/a+?/)); //a
console.log(str.match(/a{2,3}?/)); //aa
console.log(str.match(/a{2,}?/)); //aa

将所有span更换为h4 并描红,并在内容前加上 jose-

<body>
    <main>
        <span>jose</span>
        <span>wang.com</span>
        <span>josewang.com</span>
    </main>
</body>

<script>
    const main = document.querySelector('main')
    const reg = /<span>([\s\S]+?)<\/span>/gi
    main.innerHTML = main.innerHTML.replace(reg, (v, p1) => {
        console.log(v, p1)
        return `<h4 style="color:red">jose-${p1}</h4>`
    })
</script>

下面是使用禁止贪婪查找页面中的标题元素

<body>
    <h1>wang.com</h1>
    <h2>jose.com</h2>
    <h3></h3>
    <h1></h1>
</body>

<script>
    let body = document.body.innerHTML
    let reg = /<(h[1-6])>[\s\S]*?<\/\1>/gi
    console.table(body.match(reg))
</script>
15. match/matchAll
<body>
   <h1>jose.com</h1>
   <h2>wang.com</h2>
   <h1>joewang</h1>
</body>
<script>
   // 下面是使用match 全局获取页面中标签内容,但并不会返回匹配细节
   function elem(tag) {
       const reg = new RegExp('<(' + tag + ')>.+?<\.\\1>', 'g')
       return document.body.innerHTML.match(reg)
   }
   console.table(elem('h1'))

   // matchAll
   // 在新浏览器中支持使用 matchAll 操作,并返回迭代对象
   let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/gi
   const body = document.body
   const res = body.innerHTML.matchAll(reg)
   for (const iterator of res) {
       console.log('111110001', iterator)
   }
16.重写matchAll /exec
<body>
    <h1>jose.com</h1>
    <h2>wang.com</h2>
    <h1>josewang</h1>
</body>
<script>
	// 在原型定义 matchAll方法,用于在旧浏览器中工作,不需要添加g 模式运行
    String.prototype.matchAll = function (reg) {
        let res = this.match(reg)
        if (res) {
            let str = this.replace(res[0], '^'.repeat(res[0].length))
            let match = str.matchAll(reg) || []
            return [res, ...match]
        }
    }
    let str = 'josewange'
    console.dir(str.matchAll(/(e)/i))
//使用 g 模式修正符并结合 exec 循环操作可以获取结果和匹配细节
    function search(string, reg) {
        const matchs = []
        while ((data = reg.exec(string))) {
            matchs.push(data)
        }
        return matchs
    }
    console.log(search(document.body.innerHTML, /<(h[1-6])>[\s\S]+?<\/\1>/gi))
        // 使用上面定义的函数来检索字符串中的网址

let hd = `https://jose.com  
        https://www.sina.com.cn
        https://www.josewang.com`

let res = search(hd, /https?:\/\/(\w+\.)?(\w+\.)+(com|cn)/gi)
console.dir(res)
</script>
17. 字符方法
1. search

search() 方法用于检索字符串中指定的子字符串,也可以使用正则表达式搜索,返回值为索引位置

let str = "jose.com";
console.log(str.search("com"));

使用正则表达式搜索

console.log(str.search(/\.com/i));
2. match

直接使用字符串搜索

let str = "jose.com";
console.log(str.match("com"));

使用正则获取内容,下面是简单的搜索字符串

let hd = "josewang";
let res = hd.match(/j/);
console.log(res);
console.log(res[0]); //匹配的结果
console.log(res[index]); //出现的位置
3. matchAll

在新浏览器中支持使用 matchAll 操作,并返回迭代对象

let str = "josewang";
let reg = /[a-z]/ig;
for (const iterator of str.matchAll(reg)) {
  console.log(iterator);
}
4. split

用于使用字符串或正则表达式分隔字符串,下面是使用字符串分隔日期

let str = "2023-02-12";
console.log(str.split("-")); //["2023", "02", "12"]

如果日期的连接符不确定,那就要使用正则操作了

let str = "2023/02-12";
console.log(str.split(/-|\//));
5. replace

replace 方法不仅可以执行基本字符替换,也可以进行正则替换,下面替换日期连接符

let str = "2023/02/12";
console.log(str.replace(/\//g, "-")); //2023-02-12

替换字符串可以插入下面的特殊变量名:

变量说明
$$插入一个 “$”。
$&插入匹配的子串。
$`插入当前匹配的子串左边的内容。
$’插入当前匹配的子串右边的内容。
$n假如第一个参数是 RegExp 对象,并且 n 是个小于100的非负整

把所有教育汉字加上链接 https://www.jose.com

<body>
  在线教育是一种高效的学习方式,教育是一生的事业
</body>
<script>
  const body = document.body;
  body.innerHTML = body.innerHTML.replace(
    /教育/g,
    `<a href="https://www.jose.com">$&</a>`
  );
</script>

为链接添加上https ,并补全 www.

<body>
  <main>
    <a style="color:red" href="http://www.jose.com">
      开源系统
    </a>
    <a id="l1" href="http://wang.com">后盾人</a>
    <a href="http://yahoo.com">雅虎</a>
    <h4>http://www.hdcms.com</h4>
  </main>
</body>
<script>
  const main = document.querySelector("body main");
  const reg = /(<a.*href=['"])(http)(:\/\/)(www\.)?(hdcms|houdunren)/gi;
  main.innerHTML = main.innerHTML.replace(reg, (v, ...args) => {
    args[1] += "s";
    args[3] = args[3] || "www.";
    return args.splice(0, 5).join("");
  });
</script>
18.正则方法
1.test

检测输入的邮箱是否合法

<body>
  <input type="text" name="email" />
</body>

<script>
  let email = document.querySelector(`[name="email"]`);
  email.addEventListener("keyup", e => {
    console.log(/^\w+@\w+\.\w+$/.test(e.target.value));
  });
</script>
2.exec

不使用 g 修饰符时与 match 方法使用相似,使用 g 修饰符后可以循环调用直到全部匹配完。

  • 使用 g 修饰符多次操作时使用同一个正则,即把正则定义为变量使用
  • 使用 g 修饰符最后匹配不到时返回 null
    计算内容中jose出现的次数
<body>
  <div class="content">
    jose不断分享视频教程,jose网址是 jose.com
  </div>
</body>

<script>
  let content = document.querySelector(".content");
  let reg = /(?<tag>jose)/g;
  let num = 0;
  while ((result = reg.exec(content.innerHTML))) {
    num++;
  }
  console.log(`jose共出现${num}`);
</script>
19.断言匹配

断言虽然写在扩号中但它不是组,所以不会在匹配结果中保存,可以将断言理解为正则中的条件。

1.(?=exp)

零宽先行断言 ?=exp 匹配后面为 exp 的内容

把后面是wang 的jose汉字加上链接

<body>
    <main>josewang。jose--jose</main>
</body>

<script>
    const main = document.querySelector('main')
    const reg = /jose(?=wang)/gi
    main.innerHTML = main.innerHTML.replace(reg, v => `<a href="https://jose.com">${v}</a>`)
</script>

下面是将价格后面 添加上 .00

<script>
  let lessons = `
    js,200元,300次
    php,300.00元,100次
    node.js,180元,260次
  `;
  let reg = /(\d+)(.00)?(?=元)/gi;
  lessons = lessons.replace(reg, (v, ...args) => {
    args[1] = args[1] || ".00";
    return args.splice(0, 2).join("");
  });
  console.log(lessons);
</script>

使用断言验证用户名必须为五位,下面正则体现断言是不是组,并且不在匹配结果中记录

<body>
  <input type="text" name="username" />
</body>

<script>
  document
    .querySelector(`[name="username"]`)
    .addEventListener("keyup", function() {
      let reg = /^(?=[a-z]{5}$)/i;
      console.log(reg.test(this.value));
    });
</script>
2. (?<=exp)

零宽后行断言 ?<=exp 匹配前面为 exp 的内容

匹配前面是jose 的数字

let jose = "jose789wang666";
let reg = /(?<=jose)\d+/i;
console.log(jose.match(reg)); //789

匹配前后都是数字的内容

let jose = "jose789wang666";
let reg = /(?<=\d)[a-z]+(?=\d{3})/i;
console.log(jose.match(reg));

将电话的后四位模糊处理

let users = `
  jose电话: 12345678901
  wang电话: 98745675603
`;

let reg = /(?<=\d{7})\d+\s*/g;
users = users.replace(reg, str => {
  return "*".repeat(4);
});
console.log(users); //向军电话: 1234567****后盾人电话: 9874567****
3.(?!exp)

零宽负向先行断言 后面不能出现 exp 指定的内容

使用 (?!exp)字母后面不能为两位数字

let jose = "josewang12";
let reg = /[a-z]+(?!\d{2})$/i;
console.table(reg.exec(jose));

下例为用户名中不能出现jose

<body>
  <main>
    <input type="text" name="username" />
  </main>
</body>
<script>
  const input = document.querySelector(`[name="username"]`);
  input.addEventListener("keyup", function() {
    const reg = /^(?!.*jose.*)[a-z]{5,6}$/i;
    console.log(this.value.match(reg));
  });
</script>
4. (?<!exp)

零宽负向后行断言 前面不能出现exp指定的内容

获取前面不是数字的字符

let jose= "jose111wang";
let reg = /(?<!\d+)[a-z]+/i;
console.log(reg.exec(jose));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值