复习 + 一次性全搞定正则表达式

# 复习 + 一次性全搞定正则表达式

# 创建一个正则表达式

//1.字面量
var reg = /ab+c/;
//脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。

//2.调用RegExp对象的构造函数
var reg = new RegExp("ab+c");

# 正则表达式怎么用?--- 常用的方法

# 校验数据

# test(字符串)

测试字符是否满足正则表达式规则,如果测试到有,则返回true;没有则返回flase 语法:正则表达式.test(字符串) 正则表达式提供的方法

var reg = /[123]/;
var str = '1';
var result = reg.test(str);
console.log(result);//return false

# search(正则表达式)

search() 方法执行正则表达式和 String 对象之间的一个搜索匹配。 语法:字符串.search(正则表达式) 字符串提供的方法

var reg = /\d/;
var str="abcdefg3sgbh"
var res = str.search(reg);
console.log(res) //7
//验证方法 找到返回下标 找不到返回-1
//在字符串中找到满足正则表达式的那一部分

区别: .test()方法是正则表达式提供的,.search()是字符串提高的,

.test()方法返回布尔值,search()返回下标

# 提取数据

# 正则表达式.exec(字符串)

exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。 正则表达式提供的方法

var reg = /\d/;
var str = "abcd45efg";
var res = reg.exec(str);
console.log(res);//返回一个数组,内容是4
//字符串中满足正则表达式的部分提取出来
//遇到满足条件的就返回,所以只返回4

# 字符串.match(正则表达式)

match() 方法检索返回一个字符串匹配正则表达式的结果。 字符串提供的方法

var reg=/\d/
var str="abcd456efg"
var res=str.match(reg) //字符串中满足表达式的部分提取出来
console.log(res) 

区别: 正则表达式.exec(字符串),正则表达式提供的方法 字符串.match(正则表达式) 字符串的方法

相同: 都返回一个数组,只要匹配到符合规则的数据就返回

# 替换数据

# 字符串.replace(正则表达式,新的内容)

replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。 模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。字符串提供的方法

var reg=/\d/
var str="11123bcd"
var res=str.replace(reg,"a") //将数字换为a
console.log(res)//a1123bcd 只要匹配到符合规则的就返回

# 断言 Assertions

表示一个匹配在某些条件下发生。断言的组成之一是边界。对于文本、词或模式,边界可以用来表明它们的起始或终止部分(断言包括:先行断言,后行断言以及条件表达式)

//尝试一下
const text = 'A quick fox';
const reg1 = /\w+$/;
const reg2 = /\b\w+\b/g;
const reg3 = /\w+(?= fox)/;

边界类断言

字符 含义
^ 匹配输入的开头。 以xxx开始
$ 匹配输入的结束。 以xxx结束
\b 匹配一个单词的边界
\B 匹配非单词边界。

范围类 在[]组成的类内部是可以连写的

let text = 'a1B2d3X4Z5'
let reg=/[a-zA-Z]/
text.replace(reg,'Q')//Q1Q3Q4Q5

# 字符类

字符类可以区分各种字符,例如区分字母和数字。

const chessStory = 'He played the King in a8 and she moved her Queen in c2.';
const reg = /\w\d/g;
console.log(chessStory.match(reg));
// Expected output: Array [ 'a8', 'c2']

const moods = 'happy 🙂, confused 😕, sad 😢';

类型

字符 含义
[xyz] [a-c] 一个字符类。匹配包含在方括号中的任何字符。
[^xyz]
[^a-c]
一个否定或补充的字符类。也就是说,它匹配未包含在方括号中的任何字符。
. 匹配除行终止符之外的任何单个字符
\d 匹配任何数字 (阿拉伯数字)。相当于 [0-9]
\D 匹配任何非数字 (阿拉伯数字) 的字符。相当于[^0-9]
\w 匹配基本拉丁字母中的任何字母数字字符,包括下划线。相当于 [A-Za-z0-9_]
\W 匹配任何不是来自基本拉丁字母的单词字符。相当于 [^A-Za-z0-9_]
\s 匹配单个空白字符,包括空格、制表符、换页符、换行符和其他 Unicode 空格
\S 匹配除空格以外的单个字符。
\t 匹配水平制表符。
\r 匹配回车符。
\n 匹配换行符。
\v 匹配垂直制表符。
\f 匹配换页符。
[\b] 匹配退格键。如果你正在寻找单词边界字符(\b
\0 匹配一个 NUL 字符。不要在此后面加上另一个数字。
\ 对于通常按字面处理的字符,表示下一个字符是特殊的,不能按字面解释。
x|y **析取:**匹配“x”或“y”。
[\u4e00-\u9fa5]匹配任意一个中文字符

示例 寻找以 A 开头的拉丁字母单词

const aliceExcerpt =
  "I'm sure I'm not Ada,' she said, 'for her hair goes in such long ringlets, and mine doesn't go in ringlets at all.";
const regexpWordStartingWithA = /\b[aA]\w+/g;
// \b 表示边界(即不要在单词中间开始匹配)
// [aA] 表示字母 a 或 A
// \w+ 表示任何*拉丁字母*字符,多次

console.table(aliceExcerpt.match(regexpWordStartingWithA));
// ['Ada', 'and', 'at', 'all']

计算元音个数

const aliceExcerpt =
  "There was a long silence after this, and Alice could only hear whispers now and then.";
const regexpVowels = /[AEIOUYaeiouy]/g;

console.log("元音数:", aliceExcerpt.match(regexpVowels).length);
// 元音数:26

# 量词

量词表示要匹配的字符或表达式的数量。

const ghostSpeak = 'booh boooooooh';
const regexpSpooky = /bo{3,}h/;
console.log(ghostSpeak.match(regexpSpooky));
// Expected output: Array ["boooooooh"]

类型

字符集 意义
x* 将前面的项“x”匹配 0 次或更多次。
x+ 将前一项“x”匹配 1 次或更多次。等价于 {1,}
x? 将前面的项“x”匹配 0 或 1 次。
x{n} 其中“n”是一个正整数,与前一项“x”的 n 次匹配。
x{n,} 其中,“n”是一个正整数,与前一项“x”至少匹配“n”次。
x{n,m} 其中,“n”是 0 或一个正整数,“m”是一个正整数,而 m > n 至少与前一项“x”匹配,最多与“m”匹配。
x*?x+?x??x{n}?x{n,}?x{n,m}? 默认情况下,像 *+这样的量词是“贪婪的”,这意味着它们试图匹配尽可能多的字符串。量词后面的字符 ? 使量词“非贪婪”:它一旦找到匹配就会停止。例如,给定一个字符串“some new thing”: /<.*>/ 将匹配“ new /<.*?>/ 将匹配“

示例 重复模式

var wordEndingWithAs = /\w+a+/;
var delicateMessage = "This is Spartaaaaaaa";

console.table(delicateMessage.match(wordEndingWithAs)); // [ "Spartaaaaaaa" ]

# 组和反向引用

组和范围表示表达式字符的 组和范围

字符集 含义
x|y 匹配 "x" 或 "y" 任意一个字符。
[xyz]
[a-c]
字符集。 匹配任何一个包含的字符。你可以使用连字符来指定字符范围
[^xyz]
[^a-c]
一个否定的或被补充的字符集。也就是说,它匹配任何没有包含在括号中的字符。
(x) **捕获组:**匹配 x 并记住匹配项。例如,/(foo)/匹配并记住“foo bar”中的“foo”
\n 其中 n 是一个正整数。对正则表达式中与 n 括号匹配的最后一个子字符串的反向引用 (计算左括号)。
(?x) **具名捕获组:**匹配"x"并将其存储在返回的匹配项的 groups 属性中,该属性位于<Name>指定的名称下。尖括号 (<>) 用于组名。
(?:x) **非捕获组:**匹配 “x”,但不记得匹配。

# 使用组

let personList = `First_Name: John, Last_Name: Doe
First_Name: Jane, Last_Name: Smith`;

let regexpNames = /First_Name: (\w+), Last_Name: (\w+)/gm;
let match = regexpNames.exec(personList);
do {
  console.log(`Hello ${match[1]} ${match[2]}`);
} while ((match = regexpNames.exec(personList)) !== null);

# 使用命名组

let users = `姓氏:李,名字:雷
姓氏:韩,名字:梅梅`;

let regexpNames = /姓氏:(?<first>.+),名字:(?<last>.+)/gm;
let match = regexpNames.exec(users);

do {
  console.log(`Hello ${match.groups.first} ${match.groups.last}`);
} while ((match = regexpNames.exec(users)) !== null);

// Hellow 李 雷
// Hellow 韩 梅梅

# 字符类取反

很多时候碰到这么一种情况,即不想匹配某些字符,其他都匹配。此时,可以使用字符类取反——使用元字符^,创建反向类,即不属于某类的内容。

//[^abc]表示不是字符a或b或c的内容
let reg=/[^abc]/g
let text='a1b2c3d4e5'
console.log(text.replace(reg,'X')) //输出aXbXcXdXeX

# 修饰符

在正常情况下,正则匹配到第一个匹配项则停止,并且默认大小写敏感,如果想修改默认选项,则需要修饰符。

# g:global全文搜索

var reg=new RegExp('l');
var a='hello'.replace(reg,'f')
console.log(a)//输出结果为:heflo
var reg=new RegExp('l','g');//加上g标签表示全文搜索
var a='hello'.replace(reg,'f')
console.log(a)//输出结果为:heffo (所有的 l 都换成了 f )

# i:ignore case 忽略大小写

var reg=new RegExp('l','g');
var a='helloHELLO'.replace(reg,'f')
console.log(a)//输出结果为:heffoHELLO

var reg=new RegExp('l','gi');//加上i标签表示忽略大小写
var a='helloHELLO'.replace(reg,'f')
console.log(a)//输出结果为:heffoHEffO (大写和小写的l都被替换了)

# m:multiple lines 多行搜索

var reg=new RegExp('od')
var str='so good\n so good'
var result=str.replace(reg,'hi')
console.log(result)
//结果为:
 so gohi
 so good
 //只给第一行匹配了

其他标志符 s:允许 . 匹配换行符。 u:使用unicode码的模式进行匹配。 y:执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

# 贪婪模式

之前说了正则表达式的量词,但量词会带来一个到底匹配哪个的问题

var str="12345678"
var reg=/\d{3,6}/g
str.replace(reg,'X')  //X78

# 非贪婪模式

一但成功匹配不再继续尝试,这就是非贪婪模式。 只需要在量词后加上?即可

var str="12345678"
var reg=/\d{3,6}?/g
str.replace(reg,'X')  //X45678

# 分组

在使用正则表达式的时候会想要匹配一串字符串连续出现多次的情况,使用()可以达到分组的功能 例如:(hello){3} 使用符号 | (或)实现选择的功能

var str='12341235'
let reg=/123(4|5)/g
//1234 1235二选一

# 反向引用

将一种格式的时间字符串:yyyy-MM-DD转为MM/DD/yyyy类型格式字符串。 由于年月日是不固定的,没法直接转换为固定数值。这时我们可以使用反向引用解决这个问题。 利用$n,n代表着分组的序号,序号是从1开始的。

let text='2022-02-23'
let reg=/(\d{4})-(\d{2})-(\d{2})/
let res=text.replace(reg,'$3/$2/$1')//将yyyy-MM-DD转换为MM/DD/yyyy
console.log(res)