一, 什么是正则表达式?
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)
使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
搜索模式可用于文本搜索和文本替换。
二, 语法格式
/正则表达式主体/修饰符(可选)
新建正则表达式有两种方式:
- 使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:
/*
/pattern/flags
*/
const regex = /ab+c/;
const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi;
在加载脚本后,正则表达式字面值提供正则表达式的编译。当正则表达式保持不变时,使用此方法可获得更好的性能。
- 调用RegExp对象的构造函数,如下所示:
/*
new RegExp(pattern [, flags])
*/
let regex = new RegExp("ab+c");
let regex = new RegExp(/^[a-zA-Z]+[0-9]*\W?_$/, "gi");
let regex = new RegExp("^[a-zA-Z]+[0-9]*\\W?_$", "gi");
使用构造函数提供正则表达式的运行时编译。使用构造函数,当你知道正则表达式模式将会改变,或者你不知道模式,并从另一个来源,如用户输入。
三, 编写一个正则表达式的模式
正则表达式有2种表达模式:
1. 简单模式:
简单的模式是由你找到的直接匹配所构成的。比如,/abc/这个模式就匹配了在一个字符串中,仅仅字符 'abc' 同时出现并按照这个顺序。
2. 特殊字符模式
当你需要搜索一个比直接匹配需要更多条件的匹配时,比如寻找一个或多个 'b',或者寻找空格,那么这时模式将要包含特殊字符。
下面的几个表格列出了一个我们在正则表达式中可以利用的特殊字符的完整列表和描述。
- 修饰符
字符 | 含义 |
---|---|
i |
不区分大小写 |
g |
全局搜索 |
m |
多行搜索 |
y |
执行“粘性”搜索,匹配从目标字符串的当前位置开始 |
- 数量词
字符 | 含义 |
---|---|
* |
匹配前一个表达式0次或多次 |
+ |
匹配前面一个表达式1次或者多次。等价于 {1}
|
? |
匹配前面一个表达式0次或者1次。等价于 {0,1}
|
{n} |
n是一个正整数,匹配了前面一个字符刚好发生了n次 |
{n,m} |
n 和 m 都是整数。匹配前面的字符至少n次,最多m次 |
- 动态字符
字符 | 含义 | |
---|---|---|
[0-9] |
任何从 0 至 9 的数字 | |
(x) |
匹配 'x'并获取这一匹配 | |
(?:x) |
匹配 'x' 但是并不获取这一匹配 | |
[xyz] |
一个字符集合。匹配方括号的中任意字符 | |
[^xyz] |
一个反向字符集。匹配任何没有包含在方括号中的字符 | |
[a-z] |
匹配指定范围内的任意字符 a-z | |
[^a-z] |
匹配任何不在指定范围内的任意字符 | |
x(?=y) |
匹配'x'仅仅当'x'后面跟着'y'.这种叫做正向肯定查找 | |
`x | y` | 匹配’x’ 或‘y’ |
- 元字符
字符 | 含义 |
---|---|
^ |
匹配输入的开始 |
$ |
匹配输入的结束 |
\ |
转义字符 例如,模式 /a/ 代表会匹配 0 个或者多个 a。 相反,模式 /a*/ 将 '' 的特殊性移除,从而可以匹配像 "a*" 这样的字符串。 |
. |
小数点, 匹配除换行符之外的任何单个字符。 例如,/.n/将会匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',但是不会匹配 'nay' |
\d |
匹配一个数字, 等价于[0-9]
|
\D |
匹配一个非数字, 等价于[^0-9]
|
\w |
匹配一个单字字符(字母、数字或者下划线), 等价于[A-Za-z0-9_]
|
\W |
匹配一个非单字字符, 等价于[^A-Za-z0-9_]
|
\s |
匹配一个空白字符,包括空格、制表符、换页符和换行符。 等价于 [\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]
|
\S |
匹配一个非空白字符。 等价于 [^\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]
|
\n |
匹配一个换行符 |
\r |
匹配一个回车符 |
\t |
匹配一个水平制表符 |
\v |
匹配一个垂直制表符 |
\f |
匹配一个换页符 |
\b |
匹配一个词的边界。 一个词的边界就是一个词不被另外一个“字”字符跟随的位置或者没有其他“字”字符在其前面的位置。 注意,一个匹配的词的边界并不包含在匹配的内容中。换句话说,一个匹配的词的边界的内容的长度是0。(不要和 [\b] 混淆了)例子: /\bm/ 匹配“moon”中得‘m’;/oo\b/ 并不匹配"moon"中得'oo',因为'oo'被一个“字”字符'n'紧跟着。/oon\b/ 匹配"moon"中得'oon',因为'oon'是这个字符串的结束部分。这样他没有被一个“字”字符紧跟着。/\w\b\w/ 将不能匹配任何字符串,因为在一个单词中间的字符永远也不可能同时满足没有“字”字符跟随和有“字”字符跟随两种情况 |
\B |
匹配一个非单词边界。 他匹配一个前后字符都是相同类型的位置:都是“字”字符或者都不是“字”字符。 一个字符串的开始和结尾都被认为不是“字”字符,或者空字符串。 例如: /\B../ 匹配"noonday"中的'oo', 而 /y\B../ 匹配"possibly yesterday"中的’yes‘ |
[\b] |
匹配一个退格, 注意跟 \b 不一样 |
\n |
n 为具体数字 在正则表达式中,它返回最后的第n个子捕获匹配的子字符串(捕获的数目以左括号计数)。 比如 /apple(,)\sorange\1/ 匹配"apple, orange, cherry, peach."中的'apple, orange,' |
\0 |
匹配 NULL 字符 不要在这后面跟其它小数,因为 \0<digits> 是一个八进制转义序列 |
\xhh |
与代码 hh 匹配字符(两个十六进制数字) |
\uxxxx |
与代码 hhhh 匹配字符(四个十六进制数字) |
\u{hhhh} |
(仅当设置了u标志时) 使用Unicode值hhhh匹配字符 (十六进制数字). |
一张思维导图概括下:
JavaScript 正则表达式.png四, 使用
正则表达式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match、replace、search 和 split方法。
对象 | 方法 | 描述 |
---|---|---|
RegExp | exec |
一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回null)。 |
RegExp | test |
一个在字符串中测试是否匹配的RegExp方法,它返回true或false。 |
String | match |
一个在字符串中执行查找匹配的String方法,它返回一个数组或者在未匹配到时返回null。 |
String | search |
一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
String | replace |
一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 |
String | split |
一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的String方法。 |
例子:
let myRe = /d(b+)d/g;
let myArray = myRe.exec("cdbbdbsbz");
如果你不需要访问正则表达式的属性,这个脚本通过另一个方法来创建myArray:
let myArray = /d(b+)d/g.exec("cdbbdbsbz");
如果你想通过一个字符串构建正则表达式,那么这个脚本还有另一种方法:
let myRe = new RegExp("d(b+)d", "g");
let myArray = myRe.exec("cdbbdbsbz");
通过这些脚本,匹配成功后将返回一个数组并且更新正则表达式的属性,如下表所示。
正则表达式执行返回信息
对象 | 属性或索引 | 描述 | 在例子中对应的值 |
---|---|---|---|
myArray | 匹配到的字符串和所有被记住的子字符串 | ["dbbd", "bb"] | |
myArray | index | 在输入的字符串中匹配到的以0开始的索引值 | 1 |
myArray | input | 初始字符串 | "cdbbdbsbz" |
myArray | [0] | 匹配到的所有字符串(并不是匹配后记住的字符串)。 注:原文"The last matched characters.",应该是原版错误。匹配到的最终字符 |
"dbbd" |
myRe | lastIndex | 下一个匹配的索引值。 (这个属性只有在使用g参数时可用在 通过参数进行高级搜索 一节有详细的描述.) |
5 |
myRe | source | 模式文本。在正则表达式创建时更新,不执行 | "d(b+)d" |
在这个例子中如第二种形式所示,你可以使用一个正则表达式创建一个没有分配给变量的对象初始化容器。如果你这样做,那么,每一次使用时都好比在使用一个新的正则表达式。因为这个原因,如果你使用这个未分配给一个变量的正则表达式,你将在随后不能访问这个正则表达式的属性。例如,假如你有如下脚本:
let myRe = /d(b+)d/g;
let myArray = myRe.exec("cdbbdbsbz");
console.log("The value of lastIndex is " + myRe.lastIndex);
这个脚本输出如下:
The value of lastIndex is 5
然而,如果你有如下脚本:
let myArray = /d(b+)d/g.exec("cdbbdbsbz");
console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
它显示为:
The value of lastIndex is 0
当发生/d(b+)d/g使用两个不同状态的正则表达式对象,lastIndex属性会得到不同的值。如果你需要访问一个正则表达式的属性,则需要创建一个对象初始化生成器,你应该首先把它赋值给一个变量。
网友评论