Regular Expression
正则表达式是一个用来匹配字符串中字符组合的模式。
在JavaScript中,正则表达式是一个对象。
RegExp的exec和test方法以及String的 match
, replace
, search
, 和 split
方法使用到正则表达式。
创建正则表达式:
你可以用下面两种方式创建正则表达式:
1.使用正则表达式字面量创建,在斜括号中包含了正则表达式,如下
var re = /ab+c/;
正则表达式字面量在script下载的时候提供编译正则表达式。
当正则表达式一直保持不变的时候,使用上面的方法是最佳选择。
2.调用RegExp的构造函数,如下
var re = new RegExp("ab+c");
使用构造函数则在正则表达式运行的时候进行编译。
当正则表达式会改变或者正则表达式是用户输入时,采用如上构造函数方法创建。
书写正则表达式模式
一个正则表达式模式包含了简单的字符,例如/abc/
, 或者是简单字符和特殊字符的组合,例如/ab*c/
和 /Chapter (\d+)\.\d*/
.
使用简单模式
简单模式是由一些你想直接匹配的字符构成。
例如: /abc/
只是匹配了字符‘abc’,字符连接在一起且必须按照这样的顺序。这样的匹配将会在字符串"Hi, do you know your abc's?" 和"The latest airplane designs evolved from slabcraft." 中成功,但是在'Grab crab' 字符串中失败,因为它包含了字串'ab c',而不是字串'abc'。
使用特殊字符
当搜索模式不仅仅是简单的直接字符的时候,比如寻找一个或者更多的b字符,亦或寻找空格匹配等等,这些匹配模式将包含特殊字符。
例如,匹配模式/ab*c/
匹配了在一个简单的a字符后包含了一个亦或多个b字符(*意味着前一个字符出现0以上次数)后马上跟随c字符的任何的字符串。在字符串"cbbabbbbcdebc," 中匹配的字串是'abbbbc'。
下表展示了完整的特殊字符列表。
特殊字符 | 意义 |
\ | 1.作为转义字符,例如\b 2.后面的字符作为普通字符,例如\*只匹配符号* |
^ | 匹配字符串的开始
例如 /^A/不匹配字符串”an A”中的A,匹配字符串”An E”中的A |
$ |
匹配字符串的结束 |
* | 匹配前面的表达式0或多次,等价于{0,} |
+ | 匹配前面的表达式1或者多次,等价{1,} |
? | 匹配前面的表达式0或者1次,等价{0,1}
注意:在任何特殊字符*, +, ?, or {}之后马上使用?是不贪婪匹配(匹配最少的可能字符)。和默认相反的是贪婪匹配(匹配尽可能多的字符)。 比如:在字符串”123abc”中使用正则/\d+/匹配的是“123”,但是应用正则/\d+?/只匹配”1” |
. | 点号匹配任何一个简单的字符,除了换行符(newline character)
例如:/.n/匹配字符串"nay, an apple is on the tree", but not 'nay' 的结果是 'an' 和 'on',而不是’nay’ |
(x) | 匹配了x并且记住匹配内容,如下例:圆括号亦被叫做捕获型括号(capturing parenthese)
在字符串"foo bar foo bar"中应用 /(foo) (bar) \1 \2/,' |
(?:x) | 匹配x但是不记住陪陪的字符项。这里的圆括号叫做不捕获型括号(non-capturing parenthese),可以让你的定义正则表达式运算符的子表达式。
例如,如果表达式是/foo{1,2}/,字符{1,2}将匹配foo的最后一个单词o,但是使用non-capturing parenthese,使用/(?:foo){1,2}/时,字符{1,2}将匹配整个单词’foo’ |
x(?=y) | 匹配后面紧跟着y的x。
例如/Jack(?=Sprat)/匹配后面紧跟着’Sparat’的’Jack’ /Jack(?=Sprat|Frost)/匹配后面紧跟着'Sprat' 或 'Frost'的'Jack'
|
x(?!y) | 匹配后面不紧跟y的x
/\d+(?!\.)/匹配后面不紧跟着小数点的数字。
|
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次。当m省略时,默认为正无穷(∞)。
例如, /a{1,3}/ 不匹配"cndy"中的任何字符, 匹配"candy,"中的’a’, 匹配"caandy," 中的前面两个’a’,匹配 "caaaaaaandy"中的前面三个’a’。注意当匹配 "caaaaaaandy"时, 匹配的结果是"aaa", 虽然原始字符包含更多的a。
|
[xyz] | 匹配括号中个任意字符,包括转义序列。特殊字符比如*和点号.在此方括号中不再特殊,所以它们无需在方括号中转义。你可以使用连接符指定一个字符范围,如下:
[a-d]和[abcd]等价,匹配"brisket"中的”b”和“city”中个“c”。模式/[a-z.]+/和 /[\w.]+/匹配"test.i.ng"整个字符。
|
[^xyz] | 不匹配方括号中的任何字符串。例如:
[^abc]和[^a-c]等价。匹配"brisket"中的'r'。 |
[\b] | 匹配退格(backspace (U+0008)) |
\b | 匹配一个单词边界,也就是前面或者后面不包含任何的字符。
/\bm/ matches the 'm' in "moon" ;
|
\B | 匹配一个非单词边界(a non-word boundary)。它匹配了前面和后面的字符都是统一模式:要么都是包含字符,要么都是不包含字符。字符串的开始和结束被视为non-words.
例如:For example, /\B../ matches 'oo' in "noonday", and /y\B./ matches 'ye' in "possibly yesterday."
|
\cX | X是a到z之间的字母。匹配了字符串中的控制符(a control character)
For example, /\cM/ matches control-M (U+000D) in a string.
|
\d | 匹配了一个数字,等价于[0-9]
For example, /\d/ or /[0-9]/ matches '2' in "B2 is the suite number."
|
\D | 匹配了一个非数字。等价于[^0-9] .
|
\f | 匹配一个换页符(a form feed)(U+000C). |
\n | 匹配了一个换行符(a line feed (U+000A).) |
\r | 匹配了一个回车符(a carriage return (U+000D)) |
\s | 匹配了一个空格符号,包括空格键,tab键,换行符和换页符。等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] .
|
\S | 匹配了除了空格符号的character。
等价于 [^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff] .
|
\t |
Matches a tab (U+0009). |
\v |
Matches a vertical tab (U+000B). |
\w |
Matches any alphanumeric character including the underscore. Equivalent to For example, |
\W |
Matches any non-word character. Equivalent to For example, |
\n |
Where n is a positive integer, a back reference to the last substring matching the n parenthetical in the regular expression (counting left parentheses). For example, |
\0 |
Matches a NULL (U+0000) character. Do not follow this with another digit, because \0<digits> is an octal escape sequence. |
\xhh |
Matches the character with the code hh (two hexadecimal digits) |
\uhhhh |
Matches the character with the code hhhh (four hexadecimal digits). |
\u{hhhh} |
(only when u flag is set) Matches the character with the Unicode value hhhh (hexadecimal digits). |
使用圆括号
和圆括号匹配的任何字符项将被记忆。一旦被记忆,就可以被再次调用。
例如/Chapter (\d+)\.\d*/匹配的是Chapter和空格和一个或多个数字然后一个小数点再0个或者多个数字。空格后的数字将被记忆。所以"Open Chapter 4.3, paragraph 6"将匹配成功,并且4将被记忆。但是"Chapter 3 and 4"将匹配失败。
如果想要匹配一个子字符串但是又不想被记忆,那么在圆括号里面,在匹配模式之前写上?:。例如,(?:\d+)匹配的是一次或者多次的数字字符但是不会记忆匹配成功的字符串。
使用正则表达式
正则表达式被RegExp的test和exec方法使用,同时可可以被String中的match,replace,search和split方法使用。
Method | Description |
exec | 一个RegExp方法,在字符串中执行(execute)正则的匹配,返回的是数组信息 |
test | 一个RegExp方法,检测(test)字符串的匹配,返回true或false |
match | 一个String方法,在字符串中执行正则的匹配,返回数组或者当不匹配时返回null |
search | 一个String方法,在字符串中执行正则的匹配,返回匹配的字符在字符串中个位置,如果匹配失败返回-1 |
replace | 一个String方法,查找字符串中和正则匹配的字符,并用新的字符替换。 |
split | 一个String方法,使用正则亦或一个固定的字符串来讲字符串分割成数组 |
当你想知道正则在一个字符串中是否匹配,可以使用test或者search方法。
当你想获得更多的匹配信息(但是执行更慢),可以使用exec或者match方法。
当exec和match执行成功的时候,会返回一个数组,并且更新相关的正则表达式对象(the associated regular expression object)和预先定义的正则表达式对象RegExp(the predefined regular expression object,RegExp
)的属性。如果匹配失败,exec方法将会返回null
下面的例子中,使用了exec方法来在字符串中寻找匹配的内容
var myRe = /d(b+)d/g; var myArray = myRe.exec("cdbbdbsbz");
如果你不想取得有关正则表达式的详细属性,那么可以使用下面的方法:
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
你也可以使用构造函数来创建
var myRe = new RegExp("d(b+)d", "g"); var myArray = myRe.exec("cdbbdbsbz");
匹配成功之后返回的数组和更新的属性显示在下表中:
Object | Property or index | Description | In this example |
---|---|---|---|
myArray |
匹配的字符串和所有被记忆的字串 | ["dbbd", "bb"] |
|
index |
The 0-based index of the match in the input string.基于0的在字符串中第一次匹配的位置 | 1 |
|
input |
原始的字符串 | "cdbbdbsbz" |
|
[0] |
最后一个匹配的字符 | "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了,所以它们是不同的正则表达式对象,所以,它们的lastIndx属性不同。如果你想获取正则表达式的属性,你必须将其赋值给一个变量。
使用括号字串匹配
在一个包含括号的正则表达式匹配的结果将被相应保存。例如: /a(b)c/
匹配了字符串"abc"并且记忆了“b”。回调被记忆的字符,使用数组元素[1],....,[n]。
可以被记忆的子串个数是不限制的。返回的数组包含了所有匹配的内容,
下面的例子显示了如何使用和圆括号内容匹配的被记忆的字串。
下面的代码使用了repalce()方法来替换字符串中的单词。在替代字符中,代码使用了$1和$2来分别表示第一个和第二个被正则圆括号相匹配的字串。
var re = /(\w+)\s(\w+)/; var str = "John Smith"; var newstr = str.replace(re, "$2, $1"); console.log(newstr);
返回的结果是: "Smith, John".
高级搜索标签
正则表达式有4个可选标签,用来允许全局和大小写敏感搜索。
这些标签可以以任何顺序分开亦或一起使用,并且作为正则表达式的一部分。
Flag | Description |
---|---|
g |
Global search. |
i | Case-insensitive search. |
m | Multi-line search. |
y | Perform a "sticky" search that matches starting at the current position in the target string. See sticky |
在一个正则表达式中使用标签,如下使用
To include a flag with the regular expression, use this syntax:
或者
var re = new RegExp("pattern", "flags");
注意标签是正则表达式的一部分。它们不能随后被添加亦或移除。
例如: re = /\w+\s/g
创建了一个正则表达式用来寻找一个亦或更多的空格字符,并且它将在整个字符串中寻找。
var re = /\w+\s/g; //或者 var re=new RegExp("\\w+\\s", "g");
var str = "fee fi fo fum"; var myArray = str.match(re); console.log(myArray);
结果是 ["fee ", "fi ", "fo "].
标签m用于指定将多行输入的字符串当做多行来对待。如果m标签被使用,那么^和$将匹配输入字符串的任意一行的开头和结尾而不是整个字符串的开头和结束。
原文链接:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions