note
  • Introduction
  • algorithm
    • Array
    • BinarySearch
    • Bits
    • Design
    • DFS
    • DP
    • DP_bag
    • DP_stock.md
    • Hash
    • Heap
    • NodeList
    • Number
    • SlideWindow
    • Sort
    • Stack
    • String
    • Tree
  • Backend
    • express
    • koa2
    • node
    • npm
    • npx
  • db
    • mongoDB
  • Frontend
    • CSS
      • BFC
      • flex
      • layout
      • less
      • middle
      • position
      • sass
      • selector
      • 动画相关属性
      • 响应式页面
      • 层叠上下文
      • 隐藏元素
    • JS
      • Array
      • async
      • DOM
      • ES6
      • JS-军规
      • macrotask-microtask
      • practice
      • RegExp
      • this-prototype-inherit
      • type-convert
      • 前端请求
      • 浏览器加载
      • 浏览器窗口间通信
    • TS
      • note
    • Vue
      • practice
      • Component-Communicate
      • Component
      • lifecycle
      • note
      • Pinia
      • practice
      • Vue-cli
      • Vue-Router
      • Vue-Source
      • Vue2
      • Vue3
      • Vuex
    • cross-domain
    • webpack
    • 从前端角度理解缓存
    • 前端概念
    • 页面性能分析与优化
    • 页面渲染机制
  • Linux
    • basic-command
    • docker
    • java-env
    • learn
    • manage-command
    • nginx
    • Shell
    • ssh
    • tmux
    • vi
  • chrome-devtools
  • git
  • Jenkins
Powered by GitBook
On this page
  1. Frontend
  2. JS

RegExp

概述

正则表达式包括普通字符(例如,a到z之间的字母)和特殊字符(称为“元字符”)。若要匹配这些特殊字符,必须首先转义字符,即,在字符前面加反斜杠字符 \。例如,若要搜索 “+”文本字符,可使用表达式 \+。但是大多数特殊字符在中括号表达式内出现时失去本来的意义,并恢复为普通字符

构造函数

var regex = new RegExp('xyz', 'i')
var regex = new RegExp(/xyz/i)
var regex = /xyz/i

有一种情况要注意:就是如果正则中出现了反斜杠\,在用构造函数时创建正则对象时,要转义re = new RegExp("\\w+")

String相关正则方法

search()

  • 参数:要搜索的子字符串,或者一个正则表达式

  • 返回:第一个与参数匹配的子串的起始位置,如果找不到,返回-1。

  • 说明:不支持全局搜索,如果参数是字符串,会先通过RegExp构造函数转换成正则表达式

var str="i am jay"
var res=str.search("jay")
console.log(res); //5
console.log(str.search("hz"); //-1

replace()

  • 第一个参数:字符串或正则表达式

  • 第二个参数:要进行替换的字符串,也可以是函数

  • 当第二个参数是字符串时,替换文本中的$字符有特殊含义

    属性
    描述

    $1,$2,…,$99

    匹配第 1-99 个 分组里捕获的文本

    $&

    匹配到的子串文本

    $`

    匹配到的子串的左边文本

    $'

    匹配到的子串的右边文本

    $$

    美元符号

'abc'.replace(/b/g, "{$$$`$&$'}") //"a{$abc}c",即把b换成了{$abc}
"1234 2345 3456".replace(/(\d)\d{2}(\d)/g, function (match, $1, $2, index, input) {
	console.log([match, $1, $2, index, input]);
})
// => ["1234", "1", "4", 0, "1234 2345 3456"]
// => ["2345", "2", "5", 5, "1234 2345 3456"]
// => ["3456", "3", "6", 10, "1234 2345 3456"]

match()

  • 参数:要搜索的子字符串,或者一个正则表达式

  • 返回:一个由匹配结果组成的数组。与是否有修饰符g有关

  • 非全局检索:如果没有找到任何匹配的文本返回null;否则数组的第一个元素是匹配的字符串,剩下的是小括号中的子表达式,即a[n]中存放的是$n的内容。非全局检索返回三个属性:length 属性;index 属性声明的是匹配文本的第一个字符的位置;input属性则存放的是被检索的字符串 string

  • 全局检索:设置标志g则返回所有匹配子字符串,即不提供与子表达式相关的信息

let str = "2017.06.27"
let regex1 = /\b(\d+)\b/
let regex2 = /\b(\d+)\b/g
console.log(str.match(regex1))
console.log(str.match(regex2))
//['2017', '2017', index: 0, input: '2017.06.27', groups: undefined]
//['2017', '06', '27']

split()

  • 参数:正则表达式或字符串,可以有第二个参数,表示结果数组的最大长度 ,并且当正则使用分隔符时结果数组中是包含分隔符的。

  • 返回:子串组成的数组

RegExp的方法

exec()

  • 非全局检索:与String.match()非全局检索相同,返回一个数组或null

  • 全局检索:尽管是全局匹配的正则表达式,但是exec方法只对指定的字符串进行一次匹配。但是可以反复调用来实现全局检索。在 RegExp的lastIndex属性指定的字符处开始检索字符串;匹配后,将更新lastIndex为匹配文本的最后一个字符的下一个位置;再也找不到匹配的文本时,将返回null,并把 lastIndex 属性重置为 0

let str = '2017.06.27'
let regex2 = /\b(\d+)\b/g
let result
while ((result = regex2.exec(str))) {
	console.log(result, regex2.lastIndex)
}
//[ '2017', '2017', index: 0, input: '2017.06.27', groups: undefined ] 4
//[ '06', '06', index: 5, input: '2017.06.27', groups: undefined ] 7
//[ '27', '27', index: 8, input: '2017.06.27', groups: undefined ] 10

test()

  • 参数:字符串

  • 返回:true或false

字符

  • | 指示在两个或多个项之间进行选择。类似js中的或,又称分支条件

  • / 正则表达式模式的开始或结尾

  • \ 反斜杠字符,用来转义

  • []连字符 当且仅当在字符组[]的内部表示一个范围,比如[A-Z]就是表示范围从A到Z;如果需要在字符组里面表示普通字符-,放在字符组的开头或者尾部即可

  • . 匹配除换行符 \n 之外的任何单个字符

  • \d 等价[0-9],匹配0到9字符

  • \D 等价[^0-9],与\d相反

  • \s匹配空白符。与\S相反

  • \w 与以下任意字符匹配:A-Z、a-z、0-9 和下划线,等价于 [A-Za-z0-9]

  • \W 与\w相反,即 [^A-Za-z0-9]

限定符(量词字符)

显示限定符位于大括号{}中,并包含指示出现次数上下限的数值;*+?这三个字符属于单字符限定符

  • {n} 正好匹配n次

  • {n,} 至少匹配n次

  • {n,m} 匹配至少n次,至多m次

  • * 等价{0,}

  • + 等价{1,}

  • ? 等价{0,1}

注意:

  • 显示限定符中,逗号和数字之间不能有空格,否则返回null!

  • 贪婪量词*和+:javascript默认是贪婪匹配,也就是说匹配重复字符是尽可能多地匹配

  • 惰性(最少重复匹配)量词?:当进行非贪婪匹配,在待匹配的字符后面跟随一个?

var reg = /a+/
var reg2 = /a+?/
var str = 'aaab'
str.match(reg); // ["aaa"]
str.match(reg2); // ["a"]

定位点(锚字符、边界)

  • ^ 匹配开始的位置。将 ^ 用作括号[]表达式中的第一个字符,则会对字符集求反

  • $ 匹配结尾的位置

  • \b 与一个字边界匹配,如er\b 与“never”中的“er”匹配,但与“verb”中的“er”不匹配

  • \B 非边界字匹配

标记

  • 中括号[] 字符组;标记括号表达式的开始和结尾。[...] 匹配方括号内任意字符。很多字符在[]都会失去本来的意义:[^...]匹配不在方括号内的任意字符;[?.]匹配普通的问号和点号。注意:反斜杠字符\在[]中仍为转义字符。若要匹配反斜杠字符,请使用两个反斜杠\\

  • 大括号{} 标记限定符表达式的开始和结尾

  • 小括号() 标记子表达式的开始和结尾,主要作用是分组,对内容进行区分

  • (模式) 可以记住和这个模式匹配的匹配项(捕获分组)

  • (?:模式) 与模式 匹配,但不保存匹配项(非捕获分组)

  • (?=模式) 零宽正向先行断言,要求匹配与模式 匹配的搜索字符串。 找到一个匹配项后,将在匹配文本之前开始搜索下一个匹配项;但不会保存匹配项,x只有在y前面才匹配,必须写成/x(?=y)/。 解释:找一个x,那个x的后面有y

  • (?!模式) 零宽负向先行断言,要求匹配与模式 不匹配的搜索字符串。 找到一个匹配项后,将在匹配文本之前开始搜索下一个匹配项;但不会保存匹配项, x只有不在y前面才匹配,必须写成/x(?!y)/。 解释:找一个x,那个x的后面没有y

'13588884444'.replace(/(\d{3})(\d{4})(\d{4})/g, '$1****$3')
//=>  "135****4444"
'13588884444'.replace(/(\d{3})(?:\d{4})(\d{4})/g, '$1****$2')
//=>  "135****4444"
let str="Is this all there is"
let pattern=/is(?= all)/g
console.log(str.match(pattern))  //["is"]

let s = "i am jay"
let p = /j(?!ay)/g
s.match(p) //null
  • 反向引用:主要作用是给分组加上标识符

let regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/
let str1 = "2017-06-12"
let str2 = "2017/06/12"
let str3 = "2017.06.12"
let str4 = "2016-06/12"
console.log( regex.test(str1) ) // true
console.log( regex.test(str2) ) // true
console.log( regex.test(str3) ) // true
console.log( regex.test(str4) ) // false

优先级顺序

  1. \ 转义符

  2. (), (?:), (?=), [] 括号和中括号

  3. *、+、?、{n}、{n,}、{n,m} 限定符

  4. 任何元字符^、$、\ 定位点和序列

  5. | 替换

常用正则

  • 用户名校验,4到16位(字母,数字,下划线,减号)/^[a-zA-Z0-9_-]{4,16}$/

  • 校验密码强度(包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间)

    /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$/

  • 非全数字 全字母的 6-15位密码 先行否定断言 /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,15}$/

  • 版本号 X.Y.Z /^\d+(?:\.\d+){2}$/

  • 匹配连续重复的字符/(.)\1+/

  • email(支持中文邮箱)/^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/

  • 校验身份证号码(15、18位)

    ^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$

    ^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$

  • 24小时制时间(HH:mm:ss)/^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$/

  • 12小时制时间(hh:mm:ss)/^(?:1[0-2]|0?[1-9]):[0-5]\d:[0-5]\d$/

  • 提取URL链接,筛选出一段文本中的URL

    ^(f|ht){1}(tp|tps):\/\/([\\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?

  • 必须带端口号的网址或IP

    /^((ht|f)tps?:\/\/)?[\w-]+(\.[\w-]+)+:\d{1,5}\/?$/

  • html注释 /<!--[\s\S]*?-->/g

  • html标签(宽松匹配)/<(\w+)[^>]*>(.*?<\/\1>)?/

  • 提取图片标签的地址

    /<img [^>]*?src="(.*?)"[^>]*?>/g;

    \*[img][^\>]*[src] *= *[\"\']{0,1}([^\"\'\ >]*)

  • 视频(video)链接地址 (视频格式可按需增删)

    /^https?:\/\/(.+\/)+.+(\.(swf|avi|flv|mpg|rm|mov|wav|asf|3gp|mkv|rmvb|mp4))$/i

  • 图片(image)链接地址(图片格式可按需增删)

    /^https?:\/\/(.+\/)+.+(\.(gif|png|jpg|jpeg|webp|svg|psd|bmp|tif))$/i

注意事项

  1. 使用非捕获型括号 (?:...)

  2. 消除不必要括号除非需要知道 .* 匹配的最后一个字符,否则请不要使用 (.)*

  3. 不要滥用字符组 [.] 或 [*],可以通过转义转换为 \. 和 \*

  4. 使用起始锚点^

  5. 从量词中提取必须元素用 xx* 替代 x+ 能够保留匹配必须的x

  6. 提取多选结构开头的必须元素th(?:is|at) 替代 (?:this|that)

  7. 忽略优先还是匹配优先? /^.*:/ 不同于 /^.*?:/,因为前者匹配到最后的冒号,而后者匹配到第一个冒号

  8. 拆分正则表达式

  9. 将最可能匹配的多选分支放在前头

  10. 避免指数级匹配

PreviouspracticeNextthis-prototype-inherit

Last updated 2 years ago