简单使用正则(前端)

正则

创建形式

  • 正则表达式有两种定义方式,一种是通过以/开头和/结束的字符串字面量,另一种是通过new和RegExp关键字来生成

    // 构造函数创建
    const regexp = new RegExp("内容", "修饰符")
    // 直接创建 - 字面量模式
    const regexp = /.../
    

元字符

  • 概括型

    • \d:一位数字
    • \D:除数字外的任意字符
    • \w:数字、字母和下划线
    • \W:除数字、字母和下划线以外的字符
    • \s:表示空白符(包括空格、水平制表符、垂直制表符、换行符、回车符、换页符)
    • \S:非空白字符
  • 通配型

    • .:通配符,除换行外,可表示任意字符
  • 指定型

    • \r:回车符
    • \n:换行符
    • \t:制表符
    • \f:换页符
    • \v:垂直制表符
  • 其他

    • \p:检测字符属性(\p{...})
    • []:原子表,其中. + ()不被转义,不用反斜杠
    • ():原子组

使用时要被转义的元字符:([{\^$|?*+.}])

字符属性(统一大写,写于\p后边)

  • {P}:标点字符
  • {L}:字母
  • {M}:标记符号(一般不会单独出现)
  • {Z}:分隔符(比如空格、换行等)
  • {S}:符号(比如数学符号、货币符号等)
  • {N}:数字(比如阿拉伯数字、罗马数字等)
  • {C}:其他字符
  • {sc=xxx}:指定语言系统
const str = "hello samele!! 堕天使"
str.match(/\p{P}/gu) // !!
str.match(/\p{L}/gu) // h e l l o s a m e l e
src.match(/\p{sc=Han}/gu) // 堕 天 使

量词(限定词)

  • {m,}:至少出现m次
  • {m}:出现m次,等价于{m,m}
  • {m,n}:至少出现m次,最多出现n次
  • ?:对问号前一个字母或元素进行处理 - 出现0次或一次,等价于{0,1}
  • +:至少出现一次,等价于{1,}
  • *:出现任意次,等价于{0,}
  • ?的妙用(禁止贪婪)
    • 效果对比:/\d{3,6}/g会匹配尽可能多满足要求的字符,/\d{3,6}?/g会匹配最少的满足要求的字符,就是说3-6个范围内的数字都会被匹配,但是如果先匹配了3个就不会继续往下匹配了
    • 使用范围:可以加在* + {} ?后边,取区间最小值

位置

  • ^:匹配开头,若放在原子表里,表示取反(不匹配原子表内的内容)
  • $:匹配结尾,多行匹配中匹配行末尾
  • \b:匹配单词边界,即\b后面跟随的内容,其前面或者后面有分隔符(分割单词)
  • \B:非单词边界,除了上面的那些位置都是非单词边界

修饰符

  • g:全局查找
  • s:忽略换行符
  • i:不区分大小写
  • m:多行查找
  • u:Unicode模式,正确处理四个字节(宽字节)的UTF-16编码
  • y:粘附模式,从零开始(通过设置lastIndex来指定开始位置),若匹配到了就继续匹配,直到下一个匹配值不是时,停止匹配,在一定程度上节省性能

断言

此处的括号用于区分,不表示组

  • (?=内容):匹配内容后边是内容的对应内容值
  • (?<=内容):匹配内容前边是内容的对应内容值,针对的是其后面紧跟的内容,与前面的内容无关
  • (?!内容):匹配内容后边不是内容的对应内容值
  • (?<!内容):匹配内容前边不是内容的对应内容值
const str = "堕落的邪恶天使"

/堕落(?=)/.test(str) // true 此处断言针对的是其位置处的值,与前后都相关, 释:“堕落”后面是“的”
/(?<=邪恶)天使/.test(str) // true 此处断言针对的是其后面紧跟的天使,与前面是什么无关,但是整体的判断与前面相关, 释:“天使”前面是“邪恶”

原子组

  • ()框起来的内容代表分组,例如需匹配连续出现的abc,就需要使用/(abc)+/

  • 原子组中的|代表或者关系,例如(p1|p2)可代表匹配模式p1或者模式p2

  • 引用分组(捕获组):

    • 添加括号的分组可以被引用

    • 在正则表达式中还可以使用\1,\2,\3等来引用前面的分组

    • 正则表达式/\d{4}(-|/|.)\d{2}\1\d{2}/中的\1代表(-|/|.)这个分组的匹配结果,即前面是-后面也是-,前面是/后面也是/,前面是.后面也是.

      /\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/ // 两处的(-|\/|\.)毫无相关联
      //匹配2021/01.31 2021/01/31 2021-01-31 2021.01.31等-/.的随意组合
      /\d{4}(-|\/|\.)\d{2}\1\d{2}/ // \1处有一个与(-|\/|\.)同样的组值
      // 只匹配2021/01/31 2021-01-31 2021.01.31这三种
      
  • 非捕获分组:

    • 引用分组可以通过$1/1取到为捕获型分组,非捕获型分组只用来分组但不可取,非捕获分组使用(?:)
    • ?:写在组的最前方,表示对该组不进行记录,故没有该组的值
    • 注:使用.match()来匹配时,不加全局搜索
    • 使用exec()匹配时,可以用全局
const string = "ababa abbb ababab"
// 非捕获
string.match(/(?:ab)+/g) // ['abab', 'ab', 'ababab']
RegExp.$1 // ''
// 不会
string.match(/(ab)+/g) // ['abab', 'ab', 'ababab']
RegExp.$1 // 'ab'
  • ?<组别名>
    • 正则时,写在组的开始,给组起别名使用时,在替换处:在字符串内直接写对应的$<别名>就表示指定的组
const str = "堕落天使堕落人"
str.replace(/(?<samele>堕落)/g, "$<samele>的") // 堕落的天使堕落的人

转义:有特殊意义的符号需要进行转义,如 . / 等,加 \ 进行转义

特殊符号(用于替换时的字符串内简写)

  • $`
    • 正则
      • 构造函数属性
      • .leftContext的简写
      • 第一次匹配内容前面的内容
    • 字符串(.replace()仅用于字符型替换)
      • 匹配内容前面的值,用于替换当前匹配到的值
  • $'
    • 正则
      • 构造函数属性
      • .rightContext的简写
      • 获取匹配到的内容后边的内容
    • 字符串(.replace()仅用于字符型替换)
      • 匹配内容后边的值,用于替换当前匹配到的值
  • $&
    • 正则
      • 构造函数属性
      • .lastMatch简写
      • 最后匹配的内容
    • 字符串(.replace()仅用于字符型替换)
      • 匹配到的内容
  • $_:正则属性
    • 构造函数属性
    • .input的简写
    • 最后搜索的字符串
  • $+:正则属性
    • 构造函数属性
    • .lastParen的简写
    • 最后匹配到的捕获组值,若无原子组,则返回空
    • 可以通过$1 $2 $3 $4 …等来获取指定位置的组
  • $$:字符串(.replace()仅用于字符型替换)
    • $
  • $n:字符串(.replace()仅用于字符型替换)
    • 匹配第n个捕获组字符串,n取值为1~9
    • 若无组,则直接输出$n
  • $nn:字符串(.replace()仅用于字符型替换)
    • 匹配第nn个捕获组字符串,nn取值为01~99
const patten = /(a)t/igs
const src = 'bat, aat, cat, vsat'
// 正则
if (patten.test(src)) {
  console.log(RegExp.$_)
  console.log(RegExp.input) // bat, aat, cat, vsat
  console.log(RegExp["$`"])
  console.log(RegExp.leftContext) // b
  console.log(RegExp["$'"])
  console.log(RegExp.rightContext) // , aat, cat, vsat
  console.log(RegExp["$&"])
  console.log(RegExp.lastMatch) // at
  console.log(RegExp["$+"]) // a
  console.log(RegExp.$1) // a
}
// 字符串
console.log(src.replace(patten, "$1")) // ba,aa, ca, vsa
console.log(src.replace(patten, "$01")) // ba,aa, ca, vsa
console.log(src.replace(patten, "$$")) // b$,a$, c$, vs$
console.log(src.replace(patten, "$`")) // bb,abat,a, cbat,aat, c, vsbat,aat, cat, vs
console.log(src.replace(patten, "$1'")) // b,aat, cat, vsat,a, cat, vsat, c, vsat, vs
console.log(src.replace(patten, "$&")) // bat,aat, cat, vsat
src.replace(patten, (a,b,c,d,e)=> {
  // 基础三个参数,后续每个组别为一个中间参数
    // 第一个参数是匹配到的值
    // 倒数第二个参数是匹配到的值的位置(从零开始计算)
    // 最后一个参数是全字符串
    // 中间的都是组别匹配到的值
  console.log(a) // at ...
  console.log(b) // a ...
  console.log(c) // 1 ...
  console.log(d) // bat,aat, cat, vsat, aaa ...
  console.log(e) // undefined ...
})

正则属性及方法

属性

  • lastIndex:整数,源字符串中,下一次搜索的开始位置,默认始终为0

    • 当使用全局匹配时,该属性的值为匹配到的
    • 必须使用正则的方法才有用,再一个数组中.match()中是无效的
    • 若没有使用全局的匹配,返回值一直是第一个匹配到的位置
    • 使用全局匹配时,每次返回匹配到的下一个的位置
    • 要先调用对应的正则匹配方法,再调这个属性,否则只会返回零
    • 若没有匹配的的正则值,则也返回零
      const str = 'asdfavghanh'
      const regular = /a/g
      regular.exec(str) // 返回第一个匹配到的值
      regular.lastIndex // 返回第一个匹配到的值的位置
      regular.exec(str) // 返回第二个匹配到的值
      regular.lastIndex // 返回第二个匹配到的值的位置
      regular.exec(str) // 返回第累计的下一个匹配到的值
      regular.lastIndex // 返回匹配到的值对应的位置
    
  • global:布尔值,是否设置g标记

  • ignoreCase:布尔值,是否设置i标记

  • unicode:布尔值,是否设置u标记

  • sticky:布尔值,是否设置y标记

  • multiline:布尔值,是否设置m标记

  • dotAll:布尔值,是否设置s标记

  • source:正则表达式中的字面量字符串,没用开始和结束的斜杠

  • flags:正则表达式的标记字符串,没有斜杠

const patten = /at/igs
console.log(patten.global) // true
console.log(patten.ignoreCase) // true
console.log(patten.unicode) // false
console.log(patten.sticky) // false
console.log(patten.multiline) // false
console.log(patten.dotAll) // true
console.log(patten.source) // at
console.log(patten.flags) // igs

方法

  • .test()

    • 语法:正则.test(字符串)
    • 在字符串中搜索符合正则的内容,搜索到返回true
    • 搜索失败就返回false
      regular.test(str)
    
  • .exec()

    • 语法:正则.exec(字符串)
    • 只接收一个参数
    • 找到匹配项,返回包含第一个的详细信息数组,不管是不是全局匹配,都只会得到一个详细数组值
      • 返回数组的第一个值为匹配项,其余为原子组的捕获值
      • 数组具有额外属性index input
        • index:匹配到的值的起始位置
        • input:查找的整体字符串
    • 不加全局,永远匹配第一个,加全局,重复调用,每次匹配下一个
    • 找不到,则返回null
      regular.exec(str)
      
      const str = '2021-01-31'
      const reg1 = /\d{4}-\d{2}-\d{2}/
      const reg2 = /(\d{4})-(\d{2})-(\d{2})/
      str.match(reg1) // ['2021-01-31', index: 0, input: '2021-01-31', groups: undefined]
      str.match(reg2) // ['2021-01-31', '2021', '01', '31', index: 0, input: '2021-01-31', groups: undefined]
      console.log(RegExp.$1)
      // '2021'
    

字符串的方法(正则部分)

  • .search()

    • 语法:字符串.search(正则)
    • 在字符串中搜索符合规则的内容,搜索成功就返回第一个值的位置
  • 匹配失败时返回-1

      str.search(regular)
    
  • .match()

    • 语法:字符串.match(正则)
    • 查找符合正则的字符串
    • 一般加全局搜索
    • 不加全局收索时返回值和.exec()返回值一样,匹配的第一个匹配值及捕获组的值
      • 第一个元素是整体匹配结果
      • 第二个及之后的是各个分组匹配的内容
      • 后边有俩额外参数
    • 加全局搜索时,返回匹配到的所有值(仅匹配到的值)
    • 返回数据类型为数组
      str.match(regular)
    
  • .replace()

    • 语法:字符串.replace(正则,新的字符串/回调函数)
    • .match()方法一样,搜索符合规则的内容,替换成对应的字符串。
    • 返回替换后的内容。
    • 第二个参数可以是回调函数(基础三个参数,后续每个组别为一个中间参数)
      1. 第一个参数是匹配到的值
      2. 倒数第二个参数是匹配到的值的位置(从零开始计算)
      3. 最后一个参数是全字符串
      4. 中间的都是组别匹配到的值
      // 字符串型替换
      str.replace(regular, '')
      // 函数型替换
      str.replace(regular, (v,r,s) => {})
    

使用示例及常用正则

  • 常用正则

      // 提取数字 - 获得数组
      let key = str.match(/\d/g)
      // 提取汉字 - 获得数组
      let text = str.match(/[^ -~]/g)
      // 提取字母 - 获取数组
      let value = str.match(/[a-z]/ig); 
      // 获取指定区域中的内容
      let str = /<style>[\s\S]*<\/style>/.exec('指定字符串')
      // 匹配标点符号,修饰符u必须带
      let str = str.match(/\p{P}/gu)
      // 匹配字母,修饰符u必须带
      let str = str.match(/\p{L}/gu)
      // 匹配汉字,修饰符u必须带
      let str = str.match(/\p{sc=Han}/gu)
    

常用正则


// 非负整数:
^\d+$
 
// 正整数:
^[0-9]*[1-9][0-9]*$
 
// 非正整数:
^((-\d+)|(0+))$
 
// 负整数:
^-[0-9]*[1-9][0-9]*$
 
// 整数:
^-?\d+$
 
// 非负浮点数:
^\d+(\.\d+)?$
 
// 正浮点数 : 
^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)$
 
// 非正浮点数:
^((-\d+\.\d+)?)|(0+(\.0+)?))$
 
// 负浮点数:
^(-((正浮点数正则式)))$
 
// 英文字符串:
^[A-Za-z]+$
 
// 英文大写串:
^[A-Z]+$
 
// 英文小写串:
^[a-z]+$
 
// 英文字符数字串:
^[A-Za-z0-9]+$
 
// 英数字加下划线串:
^\w+$
 
// E-mail地址:
^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
 
// URL:
^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$ 
// OR
// ^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$

// 邮政编码:
^[1-9]\d{5}$
 
// 中文:
^[\u0391-\uFFE5]+$
 
// 电话号码:
^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$
 
// 手机号码:
^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$
 
// 双字节字符(包括汉字在内):
^\x00-\xff
 
// 匹配首尾空格:
(^\s*)|(\s*$)(像vbscript那样的trim函数)
 
// 匹配HTML标记:
<(.*)>.*<\/\1>|<(.*) \/>
 
// 匹配空行:
\n[\s| ]*\r
 
// 提取信息中的网络链接:
(h|H)(r|R)(e|E)(f|F)  *=  *('|")?(\w|\\|\/|\.)+('|"|  *|>)?
 
// 提取信息中的邮件地址:
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
 
// 提取信息中的图片链接:
(s|S)(r|R)(c|C)  *=  *('|")?(\w|\\|\/|\.)+('|"|  *|>)?
 
// 提取信息中的IP地址:
(\d+)\.(\d+)\.(\d+)\.(\d+)
 
// 提取信息中的中国手机号码:
(86)*0*13\d{9}
 
// 提取信息中的中国固定电话号码:
(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
 
// 提取信息中的中国电话号码(包括移动和固定电话):
(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}
 
// 提取信息中的中国邮政编码:
[1-9]{1}(\d+){5}
 
// 提取信息中的浮点数(即小数):
(-?\d*)\.?\d+
 
// 提取信息中的任何数字 :
(-?\d*)(\.\d+)? 
 
// IP:
(\d+)\.(\d+)\.(\d+)\.(\d+)
 
// 电话区号:
/^0\d{2,3}$/
 
// 腾讯QQ号:
^[1-9]*[1-9][0-9]*$
 
// 帐号(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
 
// 中文、英文、数字及下划线:
^[\u4e00-\u9fa5_a-zA-Z0-9]+$
 
// 匹配中文字符的正则表达式: 
[\u4e00-\u9fa5]
 
// 匹配双字节字符(包括汉字在内):
[^\x00-\xff]
 
// 匹配空行的正则表达式:
\n[\s| ]*\r
 
// 匹配HTML标记的正则表达式:
/<(.*)>.*<\/\1>|<(.*) \/>/
 
// sql语句:
^(select|drop|delete|create|update|insert).*$
 
// 匹配首尾空格的正则表达式:
(^\s*)|(\s*$)
 
// 匹配Email地址的正则表达式:
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值