通俗的来讲,正则表达式是一种匹配和替换的工具。如:在JS中验证手机号时,我们需要考虑用户输入的字符必须是number类型,且必须是11位的整数,且数字的前三位必须是134,155,183,188,199等等。对于这一问题,可以用if-else来实现,只不过太过于麻烦,而正则表达式就将这一问题简单化。
一个完整的正则表达式由分隔符,表达式,修饰符三部分组成。
分隔符指的是除了特殊字符以外的任意字符
表达式指的是由一些特殊字符以及非特殊字符串组成
修饰符用于开启或关闭某些功能
举个例子:
let str = "1a2b3c4d5e6"
let reg = /[abcdef]/g
// 这里表示匹配abcdef这一类的字符,匹配成功就用-进行替换
console.log(str.replace(reg, '-')); // 1-2-3-4-5-6
其中,reg中的第一个/是分隔符,两个/之间的[abcef]是表达式,g是修饰符,表示全局匹配。常见的修饰符还有i表示忽略字母大小写,m表示多行搜索,搜索时识别换行符
1、常见字符
字符
描述
[ABC]
匹配某类字符,如:[abc] 表示匹配某字符串中abc
^[ABC]
匹配某种字符之外的所有字符,如:[abc] 表示匹配某字符串中除abc之外的所有字符
[A-Z]
匹配所有大写字母
[a-z]
匹配所有小写字母
[\s]
匹配空白符,包括\f 换页符,\r 回车符,\t 水平制表符,\n 换行符,\x0b 垂直制表符等
[\S]
匹配非空白符
\w
匹配单词字符,包括数字,字母,下划线
\W
匹配非单词字符,除数字,字母,下划线之外的所有字符
.(点)
匹配除了回车符和换行符之外的所有字符
\d
匹配数字字符,等同于[0-9]
\D
匹配非数字字符,等同于^[0-9]
2、特殊字符和限定符
字符
描述
$
匹配输入字符串的结尾位置
*
匹配前面的子表达式零次或多次
+
匹配前面的子表达式一次或多次
?
匹配前面的子表达式零次或一次,或指明一个非贪婪限定符
^
匹配输入字符串的开始位置
( )
标记一个子表达式的开始和结束位置
|
指明两项之间的一个选择
{n}
n 是一个非负整数。匹配确定的 n 次
{n,}
n 是一个非负整数。至少匹配n 次
{n,m}
m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次
`注意:+ 和 *都是贪婪的,它们会尽可能多的匹配,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配`
举个例子:
JavaScript中使用RegExp对象来封装一个正则表达式,并提供相关的方法和属性。有两种创建方法,分别如下:
字面量创建方法
let reg = /\bis\b/g; //表示全局匹配左右的单词边界为is的所有字符
let str = "He is a boy. This is a dog. Where is she?";
// 这里的3个is左右两边都有完整的单词,都会匹配。
console.log(str.replace(reg, "IS")); // He IS a boy. This IS a dog. Where IS she?
构造函数创建方法
let reg = new RegExp("\bis\b", "g");
let str = "He is a boy. This is a dog. Where is she?";
console.log(str.replace(reg, "IS")); // He IS a boy. This IS a dog. Where IS she?
一般情况下,正则表达式一个字符对应字符串的一个字符。
例如:表达式 ab\t 的含义是 "ab"紧接着一个 tab(制表符)。
当需要匹配一类字符时,可以使用[ ]来构造一个简单的类。
所谓类,是指符合某些特性的对象,一个泛指,而不是特指某个字符。
例如:表达式[abc]把字符 a、b、c 归位一类,表达式可以匹配这类字符,即匹配其中之一。如:
let str = "a1b2c3d4";
let reg = /[abc]/g // 表示全局匹配字符a,b,c
console.log(str.replace(reg, "x")); // x1x2x3d4
使用元字符\^创建反向类(负向类),即匹配不属于该类的字符。
例如:[^abc]表示不是字符 a、b、c 其中之一的字符。如:
let str = "a1b2c3d4";
let reg = /[^abc]/g // 表示全局匹配字符a,b,c
console.log(str.replace(reg, "x")); // axbxcxxx
需要匹配数字时,可以使用范围类。
例如:[a-z]表示从 a 到 z 之间的任意字符,且包含 a 和 z 本身。如:
let str = "a1b2c3d4z0";
console.log(str.replace(/[a-z]/g, "X")); //全局匹配所有的小写字母并替换成X,输出结果 X1X2X3X4X0
在[ ]中可以将一些范围连续书写
let str = "a1b2c3D5E6F7";
console.log(str.replace(/[a-zA-Z0-9]/g, "*")); // 全局匹配大小写字幕和数字并替换成* 输出 ************
str = "1998-09-19";
console.log(str.replace(/[0-9-]/g, "0")); //全局匹配数字和下换线并替换成0 输出结果 0000000000
字符
描述
^
以 xxx 开始
$
以 xxx 结束
\b
单词边界
\B
非单词边界
举个例子:
let str = "This is a boy";
console.log(str.replace(/is/g, "0")); // 全局匹配所有的is,输出Th0 0 a boy
console.log(str.replace(/\bis\b/g, "0")); // This 0 a boy
console.log(str.replace(/\Bis\b/g, "0"));// 全局匹配左边界不是完整单词右边界是单词的字符,输出Th0 is a boy
let str = "@123@abc@";
console.log(str.replace(/@./g, "Q")); // 全局匹配@以及后面跟任意字符的字符,输出Q23Qbc@
console.log(str.replace(/^@./g, "Q")); // 全局匹配以@开头以及后面跟任意字符的字符,输出Q23@abc
console.log(str.replace(/.@/g, "Q")); // 全局匹配任意字符后跟@的字符,输出@12QabQ
console.log(str.replace(/.@$/g, "Q")); // 全局匹配任意字符后跟以@结尾的字符,输出@123@abQ
str = `@123
@456
@789`;
console.log(str.replace(/^@\d/g, "X"));
/* 这里表示全局匹配以@开头的数字字符进行替换,因此输出:
X23
@456
@789 */
console.log(str.replace(/^@\d/gm, "X"));
/* 这里表示全局匹配,多行搜索以@开头的数字字符进行替换,因此输出:
X23
X56
X89 */
分组()
let str = "a1b2c3d4"
console.log(str.replace(/[a-z]\d{3}/g, "X")); // 表示单独匹配3次小写字母和数字,输出a1b2c3d4
console.log(str.replace(/([a-z]\d){3}/g, "X")); // 表示匹配3次小写字母和数字组成的分组,输出Xd4
或 |,表示左右字符二选一
console.log("ByronCasper".replace(/Byron|Casper/g, "X")); // 全局匹配Byron或者Casper并进行替换,输出XX
console.log("ByrCasperByronsper".replace(/Byr(on|Ca)sper/g, "X")); // 全局匹配Byronsper或者ByrCasper并进行替换,输出XX
反向引用:使用$n的形式引用模式中分组匹配到的文本,n为索引,从1开始,如:把 2020-03-04 替换成 03/04/2020,代码如下:
// $n 反向引用
console.log("2020-03-04".replace(/(\d{4})-(\d{2})-(\d{2})/g, "$2/$3/$1")); // 表示先全局匹配4位数字-2位数字-2位数字各分组组成的字符串,再通过索引排序,并将-替换成/ 输出03/04/2020
忽略分组:当不想捕获分组时,可以使用?:直接输出$n,如:
// 忽略分组
console.log("2020-03-04".replace(/(\d{4})-(\d{2})-(?:\d{2})/g, "$2/$3/$1")); // 03/$3/2020
前瞻分为正向前瞻exp(?=assert)和负向前瞻exp(?!assert)
exp 和 assert 都是正则表达式,匹配到 exp 时还要判断 assert 是否符合,如果符合才会被匹配。
例如:表达式\w(?=\d),表示匹配到一个单词\w 时还需要向后判断是否为一个数字\d
console.log("a234V8".replace(/\w(?=\d)/g, "X")); // X2X4X8
console.log("a234V8".replace(/\w(?!\d)/g, "X")); // aX3XVX
global,是否全文搜索,默认 false。
ignoreCase,是否忽略大小写,默认 false。
multiline,是否多行搜索,默认 false。
lastIndex,当前表达式匹配内容的最后一个字符的下一个位置。
source,正则表达式的文本字符串。
举个例子:
let reg1 = /\w/;
let reg2 = /\w/gim;
console.log(reg1.global); // false
console.log(reg1.ignoreCase); // false
console.log(reg1.multiline); // false
console.log(reg2.global); // true
console.log(reg2.ignoreCase); // true
console.log(reg2.multiline); // true
//以上三个属性都是只读的。
console.log(reg2.source); // \w
举个例子:
let reg1 = /\w{1,2}/g; // 表示1~2位单词字符(包括数字,字母,下换线)
console.log(reg1.test("ab,cd")); // ab,cd符合reg1的规则,输出true
console.log(reg1.exec("ab,cd")); // [ 'cd', index: 3, input: 'ab,cd', groups: undefined ]
console.log(reg1.source); // \w{1,2}
search(reg),用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回第一个匹配结果的 index,没有匹配到返回-1。不执行全局匹配。
match(reg),检索字符串以找到一个或多个与 regexp 匹配的文本,未找到返回 null,找到后返回一个数组。与 RegExp 的 exec()方法相同。
split(reg),利用 regexp 匹配结果作为分隔符对字符串进行分割,返回一个数组。
replace(reg, newStr),将 regexp 的匹配结果替换成 newStr,返回一个新字符串。
举个例子:
let str = "
console.log(str.match(/<\S>/g)); // [ '
console.log(str.split(/[<>]/g)); // [ '', 'java', ' and ', 'javascript', ' is deferent!' ]
手机扫一扫
移动阅读更方便
你可能感兴趣的文章