你可使用如下两种方法之一构建一个正则表达式:html
使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,以下所示:git
/* /pattern/flags */ const regex = /ab+c/; const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi;
在加载脚本后,正则表达式字面值提供正则表达式的编译。当正则表达式保持不变时,使用此方法可得到更好的性能。es6
或者调用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");
使用构造函数提供正则表达式的运行时编译。使用构造函数,当你知道正则表达式模式将会改变,或者你不知道模式,并从另外一个来源,如用户输入。数组
一个正则表达式模式是由简单的字符所构成的,好比/abc/
, 或者是简单和特殊字符的组合,好比 /ab*c/
或 /Chapter (\d+)\.\d*/。后者
用到了括号,它在正则表达式中能够被用做是一个记忆设备。这一部分正则所匹配的字符将会被记住,在后面能够被利用。正如 使用括号的子字符串匹配app
简单的模式是由你找到的直接匹配所构成的。好比,/abc/
这个模式就匹配了在一个字符串中,仅仅字符 'abc' 同时出现并按照这个顺序。在 "Hi, do you know your abc's?" 和 "The latest airplane designs evolved from slabcraft." 就会匹配成功。在上面的两个实例中,匹配的是子字符串 'abc'。在字符串 "Grab crab" 中将不会被匹配,由于它不包含任何的 'abc' 子字符串。ide
当你须要搜索一个比直接匹配须要更多条件的匹配时,好比寻找一个或多个 'b',或者寻找空格,那么这时模式将要包含特殊字符。好比, 模式/ab*c/
匹配了一个单独的 'a' 后面跟了零个或者多个 'b'(*的意思是前面一项出现了零个或者多个),且后面跟着 'c' 的任何字符组合。在字符串 "cbbabbbbcdebc" 中,这个模式匹配了子字符串 "abbbbc"。函数
下面的表格列出了一个咱们在正则表达式中能够利用的特殊字符的完整列表和描述。grunt
字符 | 含义 |
---|---|
\ |
匹配将依照下列规则:性能 在非特殊字符以前的反斜杠表示下一个字符是特殊的,不能从字面上解释。例如,没有前面'\'的'b'一般匹配小写'b',不管它们出如今哪里。若是加了'\',这个字符变成了一个特殊意义的字符,意思是匹配一个字符边界。 反斜杠也能够将其后的特殊字符,转义为字面量。例如,模式 /a*/ 表明会匹配 0 个或者多个 a。相反,模式 /a\*/ 将 '*' 的特殊性移除,从而能够匹配像 "a*" 这样的字符串。 使用 new RegExp("pattern") 的时候不要忘记将 \ 进行转义,由于 \ 在字符串里面也是一个转义字符。 |
^ |
匹配输入的开始。若是多行标志被设置为true,那么也匹配换行符后紧跟的位置。 例如,/^A/ 并不会匹配 "an A" 中的 'A',可是会匹配 "An E" 中的 'A'。 当 '^' 做为第一个字符出如今一个字符集合模式时,它将会有不一样的含义。补充字符集合 一节有详细介绍和示例。 |
$ |
匹配输入的结束。若是多行标示被设置为true,那么也匹配换行符前的位置。 例如,/t$/ 并不会匹配 "eater" 中的 't',可是会匹配 "eat" 中的 't'。 |
* |
匹配前一个表达式0次或屡次。等价于 {0,}。 例如,/bo*/会匹配 "A ghost boooooed" 中的 'booooo' 和 "A bird warbled" 中的 'b',可是在 "A goat grunted" 中将不会匹配任何东西。 |
+ |
匹配前面一个表达式1次或者屡次。等价于 {1,}。 例如,/a+/匹配了在 "candy" 中的 'a',和在 "caaaaaaandy" 中全部的 'a'。 |
? |
匹配前面一个表达式0次或者1次。等价于 {0,1}。 例如,/e?le?/ 匹配 "angel" 中的 'el',和 "angle" 中的 'le' 以及"oslo' 中的'l'。 若是紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪的(匹配尽可能少的字符),和缺省使用的贪婪模式(匹配尽量多的字符)正好相反。 例如,对 "123abc" 应用 /\d+/ 将会返回 "123",若是使用 /\d+?/,那么就只会匹配到 "1"。 还能够运用于先行断言,如本表的 |
. |
(小数点)匹配除换行符以外的任何单个字符。 例如,/.n/将会匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',可是不会匹配 'nay'。 |
(x) |
匹配 'x' 而且记住匹配项,就像下面的例子展现的那样。括号被称为 捕获括号。 模式 |
(?:x) |
匹配 'x' 可是不记住匹配项。这种叫做非捕获括号,使得你可以定义为与正则表达式运算符一块儿使用的子表达式。来看示例表达式 /(?:foo){1,2}/。若是表达式是 /foo{1,2}/,{1,2}将只对 ‘foo’ 的最后一个字符 ’o‘ 生效。若是使用非捕获括号,则{1,2}会匹配整个 ‘foo’ 单词。 |
x(?=y) |
匹配'x'仅仅当'x'后面跟着'y'.这种叫作正向确定查找。 例如,/Jack(?=Sprat)/会匹配到'Jack'仅仅当它后面跟着'Sprat'。/Jack(?=Sprat|Frost)/匹配‘Jack’仅仅当它后面跟着'Sprat'或者是‘Frost’。可是‘Sprat’和‘Frost’都不是匹配结果的一部分。 |
x(?!y) |
匹配'x'仅仅当'x'后面不跟着'y',这个叫作正向否认查找。 例如,/\d+(?!\.)/匹配一个数字仅仅当这个数字后面没有跟小数点的时候。正则表达式/\d+(?!\.)/.exec("3.141")匹配‘141’可是不是‘3.141’ |
x|y |
匹配‘x’或者‘y’。 例如,/green|red/匹配“green apple”中的‘green’和“red apple”中的‘red’ |
{n} |
n是一个正整数,匹配了前面一个字符恰好发生了n次。 好比,/a{2}/不会匹配“candy”中的'a',可是会匹配“caandy”中全部的a,以及“caaandy”中的前两个'a'。 |
{n,m} |
n 和 m 都是整数。匹配前面的字符至少n次,最多m次。若是 n 或者 m 的值是0, 这个值被忽略。 例如,/a{1, 3}/ 并不匹配“cndy”中的任意字符,匹配“candy”中的a,匹配“caandy”中的前两个a,也匹配“caaaaaaandy”中的前三个a。注意,当匹配”caaaaaaandy“时,匹配的值是“aaa”,即便原始的字符串中有更多的a。 |
[xyz] |
一个字符集合。匹配方括号的中任意字符,包括转义序列。你可使用破折号(-)来指定一个字符范围。对于点(.)和星号(*)这样的特殊符号在一个字符集中没有特殊的意义。他们没必要进行转义,不过转义也是起做用的。 例如,[abcd] 和[a-d]是同样的。他们都匹配"brisket"中得‘b’,也都匹配“city”中的‘c’。/[a-z.]+/ 和/[\w.]+/都匹配“test.i.ng”中的全部字符。 |
[^xyz] |
一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可使用破折号(-)来指定一个字符范围。任何普通字符在这里都是起做用的。 例如,[^abc] 和 [^a-c] 是同样的。他们匹配"brisket"中的‘r’,也匹配“chop”中的‘h’。 |
[\b] |
匹配一个退格(U+0008)。(不要和\b混淆了。) |
\b |
匹配一个词的边界。一个词的边界就是一个词不被另一个“字”字符跟随的位置或者没有其余“字”字符在其前面的位置。注意,一个匹配的词的边界并不包含在匹配的内容中。换句话说,一个匹配的词的边界的内容的长度是0。(不要和[\b]混淆了) 例子: /\bm/匹配“moon”中得‘m’; /oo\b/并不匹配"moon"中得'oo',由于'oo'被一个“字”字符'n'紧跟着。 /oon\b/匹配"moon"中得'oon',由于'oon'是这个字符串的结束部分。这样他没有被一个“字”字符紧跟着。 /\w\b\w/将不能匹配任何字符串,由于在一个单词中间的字符永远也不可能同时知足没有“字”字符跟随和有“字”字符跟随两种状况。 注意: JavaScript的正则表达式引擎将特定的字符集定义为“字”字符。不在该集合中的任何字符都被认为是一个断词。这组字符至关有限:它只包括大写和小写的罗马字母,十进制数字和下划线字符。不幸的是,重要的字符,例如“é”或“ü”,被视为断词。 |
\B |
匹配一个非单词边界。他匹配一个先后字符都是相同类型的位置:都是“字”字符或者都不是“字”字符。一个字符串的开始和结尾都被认为不是“字”字符,或者空字符串。 例如,/\B../匹配"noonday"中的'oo', 而/y\B../匹配"possibly yesterday"中的’yes‘ |
\cX |
当X是处于A到Z之间的字符的时候,匹配字符串中的一个控制符。 例如, |
\d |
匹配一个数字
例如, |
\D |
匹配一个非数字字符
例如, |
\f |
匹配一个换页符 (U+000C)。 |
\n |
匹配一个换行符 (U+000A)。 |
\r |
匹配一个回车符 (U+000D)。 |
\s |
匹配一个空白字符,包括空格、制表符、换页符和换行符。 等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。 例如, |
\S |
匹配一个非空白字符。 等价于 例如, |
\t |
匹配一个水平制表符 (U+0009)。 |
\v |
匹配一个垂直制表符 (U+000B)。 |
\w |
匹配一个单字字符(字母、数字或者下划线)。 等价于 例如, |
\W |
匹配一个非单字字符。 等价于 例如, |
\n |
在正则表达式中,它返回最后的第n个子捕获匹配的子字符串(捕获的数目以左括号计数)。 好比 |
\0 |
匹配 NULL (U+0000) 字符, 不要在这后面跟其它小数,由于 \0<digits> 是一个八进制转义序列。 |
\xhh |
与代码 hh 匹配字符(两个十六进制数字) |
\uhhhh |
与代码 hhhh 匹配字符(四个十六进制数字)。 |
\u{hhhh} |
(仅当设置了u标志时) 使用Unicode值hhhh匹配字符 (十六进制数字). |
将用户输入转义为正则表达式中的一个字面字符串, 能够经过简单的替换来实现:
function escapeRegExp(string){ return string.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$&"); //$&表示整个被匹配的字符串 }
任何正则表达式的插入语都会使这部分匹配的副字符串被记忆。一旦被记忆,这个副字符串就能够被调用于其它用途,如同 使用括号的子字符串匹配之中所述。
好比, /Chapter (\d+)\.\d*/
解释了额外转义的和特殊的字符,并说明了这部分pattern应该被记忆。它精确地匹配后面跟着一个以上数字字符的字符 'Chapter ' (\d
意为任何数字字符,+ 意为1次以上
),跟着一个小数点(在这个字符中自己也是一个特殊字符;小数点前的 \ 意味着这个pattern必须寻找字面字符 '.'),跟着任何数字字符0次以上。 (\d
意为数字字符, *
意为0次以上)。另外,插入语也用来记忆第一个匹配的数字字符。
此模式能够匹配字符串"Open Chapter 4.3, paragraph 6",而且'4'将会被记住。此模式并不能匹配"Chapter 3 and 4",由于在这个字符串中'3'的后面没有点号'.'。
括号中的"?:",这种模式匹配的子字符串将不会被记住。好比,(?:\d+)匹配一次或屡次数字字符,可是不能记住匹配的字符。
正则表达式能够被用于RegExp
的exec
和test
方法以及 String
的match
、replace
、search
和split
方法。这些方法在JavaScript 手册中有详细的解释。
方法 | 描述 |
---|---|
exec |
一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回null)。 |
test |
一个在字符串中测试是否匹配的RegExp方法,它返回true或false。 |
match |
一个在字符串中执行查找匹配的String方法,它返回一个数组或者在未匹配到时返回null。 |
search |
一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
replace |
一个在字符串中执行查找匹配的String方法,而且使用替换字符串替换掉匹配到的子字符串。 |
split |
一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的String方法。 |
当你想要知道在一个字符串中的一个匹配是否被找到,你可使用test或search方法;想获得更多的信息(可是比较慢)则可使用exec或match方法。若是你使用exec或match方法而且匹配成功了,那么这些方法将返回一个数组而且更新相关的正则表达式对象的属性和预约义的正则表达式对象(详见下)。若是匹配失败,那么exec方法返回null(也就是false)。
在接下来的例子中,脚本将使用exec方法在一个字符串中查找一个匹配。
var myRe = /d(b+)d/g; var myArray = myRe.exec("cdbbdbsbz");
若是你不须要访问正则表达式的属性,这个脚本经过另外一个方法来建立myArray:
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
若是你想经过一个字符串构建正则表达式,那么这个脚本还有另外一种方法:
var myRe = new RegExp("d(b+)d", "g"); var myArray = myRe.exec("cdbbdbsbz");
经过这些脚本,匹配成功后将返回一个数组而且更新正则表达式的属性,以下表所示。
对象 | 属性或索引 | 描述 | 在例子中对应的值 |
---|---|---|---|
myArray |
匹配到的字符串和全部被记住的子字符串。 | ["dbbd", "bb"] |
|
index |
在输入的字符串中匹配到的以0开始的索引值。 | 1 |
|
input |
初始字符串。 | "cdbbdbsbz" |
|
[0] |
匹配到的全部字符串(并非匹配后记住的字符串)。注:原文"The last matched characters.",应该是原版错误。匹配到的最终字符。 | "dbbd" |
|
myRe |
lastIndex |
下一个匹配的索引值。(这个属性只有在使用g参数时可用在 经过参数进行高级搜索 一节有详细的描述.) | 5 |
source |
模式文本。在正则表达式建立时更新,不执行。 | "d(b+)d" |
在这个例子中如第二种形式所示,你可使用一个正则表达式建立一个没有分配给变量的对象初始化容器。若是你这样作,那么,每一次使用时都比如在使用一个新的正则表达式。由于这个缘由,若是你使用这个未分配给一个变量的正则表达式,你将在随后不能访问这个正则表达式的属性。例如,假如你有以下脚本:
var myRe = /d(b+)d/g; var myArray = myRe.exec("cdbbdbsbz"); console.log("The value of lastIndex is " + myRe.lastIndex);
这个脚本输出以下:
The value of lastIndex is 5
然而,若是你有以下脚本:
var 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属性会获得不一样的值。若是你须要访问一个正则表达式的属性,则须要建立一个对象初始化生成器,你应该首先把它赋值给一个变量。
一个正则表达式模式使用括号,将致使相应的子匹配被记住。例如,/a(b)c /能够匹配字符串“abc”,而且记得“b”。回调这些括号中匹配的子串,使用数组元素[1],……[n]。
使用括号匹配的子字符串的数量是无限的。返回的数组中保存全部被发现的子匹配。下面的例子说明了如何使用括号的子字符串匹配。
下面的脚本使用replace()方法来转换字符串中的单词。在匹配到的替换文本中,脚本使用替代的$ 1,$ 2表示第一个和第二个括号的子字符串匹配。
var re = /(\w+)\s(\w+)/; var str = "John Smith"; var newstr = str.replace(re, "$2, $1"); console.log(newstr);
这个表达式输出 "Smith, John"。
正则表达式有四个可选参数进行全局和不分大小写搜索。这些参数既能够单独使用也能够一块儿使用在任何顺序和包含正则表达式的部分中。
标志 | 描述 |
---|---|
g |
全局搜索。 |
i | 不区分大小写搜索。 |
m | 多行搜索。 |
y | 执行“粘性”搜索,匹配从目标字符串的当前位置开始,可使用y标志。 |
包含一个标志的正则表达式,使用这个表达式:
var re = /pattern/flags;
或者
var re = new RegExp("pattern", "flags");
值得注意的是,标志是一个正则表达式的一部分,它们在接下来的时间将不能添加或删除。
例如,re = /\w+\s/g 将建立一个查找一个或多个字符后有一个空格的正则表达式,或者组合起来像此要求的字符串。
var re = /\w+\s/g; var str = "fee fi fo fum"; var myArray = str.match(re); console.log(myArray);
这段代码将输出 ["fee ", "fi ", "fo "]。在这个例子中,你能够将:
var re = /\w+\s/g;
替换成:
var re = new RegExp("\\w+\\s", "g");
而且能获取到相同的结果。
m标志用于指定多行输入字符串应该被视为多个行。若是使用m标志,^和$匹配的开始或结束输入字符串中的每一行,而不是整个字符串的开始或结束。