在线验证工具
字符
元字符
| 元字符 | 描述 |
|---|---|
| . | 匹配除换行符以外的任意字符 |
| \d | 匹配数字, 等价于字符组[0-9] |
| \w | 匹配字母, 数字, 下划线 |
| \s | 匹配任意的空白符(包括制表符,空格,换行等) |
| \b | 匹配单词开始或结束的位置 |
| 匹配行首 | |
| $ | 匹配行尾 |
| \D | 匹配非数字的任意字符, 等价于[^0-9] |
| \W | 匹配除字母,数字,下划线之外的任意字符 |
| \S | 匹配非空白的任意字符 |
| \B | 匹配非单词开始或结束的位置 |
| [^x] | 匹配除x以外的任意字符 |
| * | x>=0 |
| + | x>=1 |
| ? | x=0 or x=1 |
| {n} | x=n |
| {n,} | x>=n |
| {n,m} | n<=x<=m |
字符组
[…] 匹配中括号内字符之一. 如: [abc] 匹配字符 a, b 或 c;如果中括号中包含元字符或限定符, 则元字符或限定符降级为普通字符, 不再具有元字符或限定符的功能, 如 [+.?] 匹配 加号, 点号或问号。
如果[]中出现-
- 如果是[0-9a-zA-Z],-则表示的是一个区间,0到9、a到z、A到Z,不会匹配到-
- 如果是要匹配到-,则加上转义符 \ 即可
排除性字符组
[^…] 匹配任何未列出的字符; 如: [^a] 匹配除a以外的任意字符。
多选结构
| 就是或的意思,表示两者中的一个;如: x|y 匹配x或者y字符。
括号
() 常用来界定重复限定符的范围,以及将字符分组;如: (ab)+ 可以匹配abab..等, 其中 ab 便是一个分组。
转义字符
** 即转义字符, 通常 \ * + ? | { [ ( ) ] }^ $ . # 和 空白 这些字符都需要转义.
操作符的运算优先级
- \ 转义符
- (), (?:), (?=), [] 圆括号或方括号
- *, +, ?, {n}, {n,}, {n,m} 限定符
- ^, $ 位置
- | “或” 操作
修饰符
javaScript中正则表达式默认有如下五种修饰符:
- g (全文查找), 如上述截图, 实际上就开启了全文查找模式.
- i (忽略大小写查找)
- m (多行查找)
- y (ES6新增的粘连修饰符)
- u (ES6新增)
测试
我们来测试下上面的知识点, 写一个匹配手机号码的正则表达式, 如下:
(\+86)?1\d{10}
- “+86” 匹配文本 “+86”, 后面接元字符问号,,表示可匹配1次或0次, 合起来表示 “(+86)?” 匹配 “+86” 或者 “”
- 普通字符”1” 匹配文本 “1”
- 元字符 “\d” 匹配数字0到9,区间量词 “{10}” 表示匹配 10 次,合起来表示 “\d{10}” 匹配连续的10个数字
以上, 匹配结果如下:
贪婪模式和非贪婪模式
默认情况下, 所有的量词 *、 +、? 或 {}都是贪婪模式, 表示尽可能多的去捕获字符; 而在量词后增加 ? , 则是非贪婪模式, 表示尽可能少的去捕获字符. 如下:
var str = 'aaab';
str.match(/a+/) // ["aaa", index: 0, input: "aaab", groups: undefined]
str.match(/a+?/) // ["a", index: 0, input: "aaab", groups: undefined]
str.match(/a{2,3}/) // ["aaa", index: 0, input: "aaab", groups: undefined]
str.match(/a{2,3}?/) // ["aa", index: 0, input: "aaab", groups: undefined]
在String.prototype.replace()中运用正则表达式
replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。
语法
str.replace(regexp|substr, newSubStr|function)
- regexp (pattern):一个RegExp 对象或者其字面量。该正则所匹配的内容会被第二个参数的返回值替换掉。
- substr (pattern):一个将被 newSubStr 替换的 字符串。其被视为一整个字符串,而不是一个正则表达式。仅第一个匹配项会被替换。
- newSubStr (replacement):用于替换掉第一个参数在原字符串中的匹配部分的字符串。该字符串中可以内插一些特殊的变量名。参考下面的使用字符串作为参数。
- function (replacement):一个用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果。参考下面的指定一个函数作为参数。
tip: 在进行全局的搜索替换时,正则表达式需包含 g 标志。
第一个参数是正则时的几种情况
- 第一个参数是正则,第二个参数是带$符的字符串
var str3 = '这是一段原始文本,"3c这要替换4d"!';
var newStr = str3.replace( /([0-9])([a-z])/g,"$1" );
console.log( newStr ); //输出: 这是一段原始文本,"3这要替换4"!';
替换字符串可以插入下面的特殊变量名:
| 变量名 | 代表的值 |
|---|---|
| $$ | 插入一个 "$"。 |
| $& | 插入匹配的子串。 |
| $` | 插入当前匹配的子串左边的内容。 |
| $' | 插入当前匹配的子串右边的内容。 |
| $n | 假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从1开始。如果不存在第 n个分组,那么将会把匹配到到内容替换为字面量。比如不存在第3个分组,就会用“$3”替换匹配到的内容。 |
| $Name | 这里Name 是一个分组名称。如果在正则表达式中并不存在分组(或者没有匹配),这个变量将被处理为空字符串。只有在支持命名分组捕获的浏览器中才能使用。 |
- 第一个参数是正则,第二个参数是函数 你可以指定一个函数作为第二个参数。在这种情况下,当匹配执行后,该函数就会执行。 函数的返回值作为替换字符串。 (注意:上面提到的特殊替换参数在这里不能被使用。) 另外要注意的是,如果第一个参数是正则表达式,并且其为全局匹配模式,那么这个方法将被多次调用,每次匹配都会被调用。
函数的参数:
| 变量名 | 代表的值 |
|---|---|
| match | 匹配的子串。(对应于上述的$&。) |
| p1,p2, ... | 假如replace()方法的第一个参数是一个RegExp 对象,则代表第n个括号匹配的字符串。(对应于上述的2等。)例如,如果是用 /(\a+)(\b+)/ 这个来匹配,p1 就是匹配的 \a+,p2 就是匹配的 \b+ |
| offset | 匹配到的子字符串在原字符串中的偏移量。(比如,如果原字符串是 'abcd',匹配到的子字符串是 'bc',那么这个参数将会是 1) |
| string | 被匹配的原字符串 |
| NamedCaptureGroup | 命名捕获组匹配的对象 |
(精确的参数个数依赖于 replace() 的第一个参数是否是一个正则表达式(RegExp)对象,以及这个正则表达式中指定了多少个括号子串,如果这个正则表达式里使用了命名捕获, 还会添加一个命名捕获的对象)
var str = '测试文本1a测试文本2b';
var newStr = str.replace( /([0-9])([a-z])/g,function (match, p1, p2, offset, string){
console.log( match );
console.log( p1 );
console.log( p2 );
console.log( offset );
console.log( string );
} );
//输出:
1a
1
a
4
测试文本1a测试文本2b
2b
2
b
10
测试文本1a测试文本2b
function replacer(match, p1, p2, p3, offset, string) {
return [p1, p2, p3].join(' - ');
}
var newString = 'abc12345#$*%'.replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
console.log(newString); // abc - 12345 - #$*%