一、基础知识
补充:
return RegExp.$1;RegExp的静态变量,$n,表示的是最近一次使用的正则对象的匹配到的第n个符合正则对象规则要求的元素(只有 $1 ~ $9 )。找到了就将其返回,未找到返回空。
1.创建正则
(/u/.test(hd)) /true
new RegExp(pattern, attributes);pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式
其返回值是一个新的 RegExp 对象,具有指定的模式和标志。如果参数 pattern 是正则表达式而不是字符串,那么 RegExp() 构造函数将用与指定的 RegExp 相同的模式和标志创建一个新的 RegExp 对象。如果不用 new 运算符,而将 RegExp() 作为函数调用,那么它的行为与用 new 运算符调用时一样,只是当 pattern 是正则表达式时,它只返回 pattern,而不再创建一个新的 RegExp 对象。
使用例子:let hd = "houdunren.com"; let web = "houdunren"; let reg = new RegExp(web); console.log(reg.test(hd)); //true
2.选择符
const hd = "houdunren"; console.log(/houdunren|hdcms/.test(hd)); //true
3.字符转义
let price = 12.23; //含义1: . 除换行外任何字符 含义2: .普通点 console.log(/\d+\.\d+/.test(price)); //因为在字符串中 \d 与 d 是相等的,所以在 new RegExp 时\d 就是一个普通字母d \.也代表 . 并不能起到匹配数字的作用 所以需要加上两个\\ console.log("\d" == "d"); //使用对象定义正则时,可以先把字符串打印一样,结果是字面量一样的定义就对了 console.log("\\d+\\.\\d+"); let reg = new RegExp("\\d+\\.\\d+");//需要把\d \. 前面都需要再转义一次! console.log(reg.test(price));
4.字符边界
边界符 | 说明 |
---|---|
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束,忽略换行符 |
const hd = "www.houdunren.com"; console.log(/^www/.test(hd)); //true
匹配内容必须以.com结束
const hd = "www.houdunren.com"; console.log(/\.com$/.test(hd)); //true
二、元子字符
1.字符列表
元字符 | 说明 | 示例 |
---|---|---|
\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] |
. | 匹配除换行符外的任意字符 |
正则中空格会按普通字符对待
let tel = `010 - 999999`; console.log(/\d+-\d+/.test(tel)); //false console.log(/\d+ - \d+/.test(tel)); //true
2.所有字符
三、模式修饰
修饰符 | 说明 |
---|---|
i | 不区分大小写字母的匹配 |
g | 全局搜索所有匹配内容 |
m | 视为多行 |
s | 视为单行忽略换行符,使用. 可以匹配所有字符 |
y | 从 regexp.lastIndex 开始匹配 |
u | 正确处理四个字符的 UTF-16 编 |
- 必须结合 g 修饰符使用
- 对 exec 方法有效(在后面全局匹配中详细总结)
- 匹配完成时,lastIndex 会被重置为0
四、原子表
原子表 | 说明 |
---|---|
[] | 只匹配其中的一个原子 如 [ue] 代表匹配u e中任何一个字符就可以 而不是看作整体 |
[^] | 只匹配"除了"其中字符的任意一个原子 |
[0-9] | 匹配0-9任何一个数字 |
[a-z] | 匹配小写a-z任何一个字母 |
[A-Z] | 匹配大写A-Z任何一个字母 |
五、原子组
- 原子组与原子表的差别在于原子组一次匹配多个元子,而原子表则是匹配任意一个字符
- 元字符组用 () 包裹
1.基本使用
使用原子组匹配标题元素
let hd = ` <h1>houdunren</h1> <span>后盾人</span> <h2>hdcms</h2> `; console.table(hd.match(/<(h[1-6])[\s\S]*<\/\1>/g));
2.邮箱匹配
使用原子组匹配邮箱
let hd = "2300071698@qq.com"; let reg = /^[\w\-]+@[\w\-]+\.(com|org|cn|cc|net)$/i; console.dir(hd.match(reg));
3.引用分组
let hd = ` <h1>houdunren</h1> <span>后盾人</span> <h2>hdcms</h2> `; let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi;(这里的\1代表引用第一个原子组) console.log(hd.replace(reg, `<p>$2</p>`));(这里的$2指使用第二个原子组的内容做替换)
4.分组别名
如果希望返回的组数据更清晰,可以为原子组编号,结果将保存在返回的 groups字段中
let hd = "<h1>houdunren.com</h1>"; console.dir(hd.match(/<(?<tag>h[1-6])[\s\S]*<\/\1>/));
组别名使用 ?<> 形式定义,下面将标签替换为p标签
let hd = ` <h1>houdunren</h1> <span>后盾人</span> <h2>hdcms</h2> `; let reg = /<(?<tag>h[1-6])>(?<con>[\s\S]*)<\/\1>/gi; console.log(hd.replace(reg, `<p>$<con></p>`));
六、重复匹配
如果要重复匹配一些内容时我们要使用重复匹配修饰符,包括以下几种:
符号 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
let hd = "010-12345678"; console.log(/0\d{2,3}-\d{7,8}/.exec(hd));
使用 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复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
七、全局匹配
1.matchAll
let str = "houdunren"; let reg = /[a-z]/ig; for (const iterator of str.matchAll(reg)) { console.log(iterator); }2
2.exec
使用 g 模式修正符并结合 exec 循环操作可以获取结果和匹配细节
<body> <h1>houdunren.com</h1> <h2>hdcms.com</h2> <h1>后盾人</h1> </body> <script> 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)); </script>
八、字符方法
1.search
search() 方法用于检索字符串中指定的子字符串,也可以使用正则表达式搜索,返回值为索引位置
console.log(str.search(/\.com/i));
2.match
变量 | 说明 |
---|---|
0 | 匹配到的完整内容 |
1,2.... | 匹配到的原子组 |
index | 原字符串中的位置 |
input | 原字符串 |
groups | 命名分组 |
在match中使用原子组匹配,会将每个组数据返回到结果中
- 0 为匹配到的完整内容
- 1/2 等 为原子级内容
- index 匹配的开始位置
- input 原始数据
- groups 组别名
let hd = "houdunren.com"; console.log(hd.match(/houdun(ren)\.(com)/)); //["houdunren.com", "ren", "com", index: 0, input: "houdunren.com", groups: undefined]
let body = document.body.innerHTML; let result = body.match(/<(h[1-6])>[\s\S]+?<\/\1>/g); console.table(result);
3.matchAll
let str = "houdunren"; 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(/-|\//));
5.replace
replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串stringObject.replace(regexp/substr,replacement)
参数 | 描述 |
---|---|
regexp/substr | 必需。规定子字符串或要替换的模式的 RegExp 对象。 请注意,如果该值是一个字符串,则将它作为要检索的直接量文本模式,而不是首先被转换为 RegExp 对象。 |
replacement | 必需。一个字符串值。规定了替换文本或生成替换文本的函数。 |
替换字符串可以插入下面的特殊变量名:
变量 | 说明 |
---|---|
$$ | 插入一个 "$"。 |
$& | 插入匹配的子串。 |
$` | 插入当前匹配的子串左边的内容。 |
$' | 插入当前匹配的子串右边的内容。 |
$n | 假如第一个参数是 RegExp 对象,并且 n 是个小于100的非负整数 那么插入第 n 个括号匹配的字符串。提示:索引是从1开始 (即之前提到的原子组替换) |
把电话号用 - 连接
let hd = "(010)99999999 (020)8888888"; console.log(hd.replace(/\((\d{3,4})\)(\d{7,8})/g, "$1-$2"))
在后盾人前后添加三个=
let hd = "=后盾人="; console.log(hd.replace(/后盾人/g, "$`$`$&$'$'"));
变量名 | 代表的值 |
---|---|
match | 匹配的子串。(对应于上述的$&。) |
p1,p2, ... | 假如replace()方法的第一个参数是一个 RegExp 对 象则代表第n个括号匹配的字符串。(对应于上述的$1,$2等。) 例如,如果是用 /(\a+)(\b+)/ 这个来匹配, p1 就是匹配的 \a+,p2 就是匹配的 \b+。 |
offset | 匹配到的子字符串在原字符串中的偏移量。 (比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc', 那么这个参数将会是 1) |
string | 被匹配的原字符串。 |
NamedCaptureGroup | 命名捕获组匹配的对象 |
九、正则方法
1.test
var str = "Visit W3School"; var patt1 = new RegExp("W3School"); var result = patt1.test(str);//输出:true
2.exec
注意:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0,否则将直接从下一位置开始进行匹配
十、断言匹配
1.(?=exp)
零宽先行断言 ?=exp 匹配后面为 exp 的内容将价格后面 添加上 .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>
2.(?<=exp)
匹配前后都是数字的内容
let hd = "houdunren789hdcms666"; let reg = /(?<=\d)[a-z]+(?=\d{3})/i; console.log(hd.match(reg));
3.(?!exp)
let hd = "houdunren12"; let reg = /[a-z]+(?!\d{2})$/i; console.table(reg.exec(hd));
4.(?<!exp)
获取前面不是数字的字符
let hd = "hdcms99houdunren"; let reg = /(?<!\d+)[a-z]+/i; console.log(reg.exec(hd)); //hdcms
5.(?<!exp)
零宽负向后行断言 前面不能出现exp指定的内容
获取前面不是数字的字符
let hd = "hdcms99houdunren"; let reg = /(?<!\d+)[a-z]+/i; console.log(reg.exec(hd)); //hdcms