JavaScript正则表达式

来源:互联网 发布:金庸男主角知乎 编辑:程序博客网 时间:2024/06/15 23:50

正则表达式 是一个描述字符模式的对象,JavaScript的RegExp类表示正则表达式,String和RegExp都定义了方法,后者使用正则表达式进行强大的模式匹配和文本检索与替换功能。

JavaScript中的正则表达式用RegExp对象表示,可以使用RegExp()构造函数来创建RegExp对象,不过RegExp对象更多的是通过一种特殊的直接量语法来创建,正则表达式直接量定义为包含在一对斜线之间的字符,如下两种用法等效,都是用来匹配所有以字母“s”结尾的字符串:

var pattern = /s$/var pattern = new RegExp(“s$”);

正则表达式中的所有字母和数字都是按照字面含义进行匹配的,JavaScript正则表达式语法也支持非字母的字符匹配,这些字符需要通过反斜线\作为前缀进行转义,如下所示正则表达式中的直接量字符(许多标点符号具有特殊含义,如^ $ . * + ? = ! : | / \ ( ) [ ] { }):

字母和数字字符:本身\o:NUL字符\t:制表符\n:换行符\v:垂直制表符\f:换页符\r:回车符\xnn:由十六进制数nn指定的拉丁字符\unnnn:有十六进制数nnnn指定的Unicode字符\cX:控制字符^X

将直接量字符单独放入方括号内就组成了字符类,一个字符类可以匹配它所包含的任意字符,下面列出正则表达式的字符类:

[...]:方括号内的任意字符,如[abc]表示a、b和c中的任意一个字符,[a-z]表示任意一个小写字母,[a-zA-Z0-9]表示任意一个字母或者数字。[^...]:不在方括号内的任意字符,如[^abc]表示除了a、b和c的其它任意一个字符。.:除换行符和其他Unicode行终止符之外的任意字符\w:任何ASCII字符组成的单词\W:任何不是ASCII字符组成的单词`这里写代码片`\s:任何Unicode空白符\S:任何非Unicode空白符的字符\d:任何ASCII数字\D:任何ASCII数字之外的任何字符[\b]:退格直接量(特例)

如果正则表达式中多个字符重复多次,一个一个写起来难免显得麻烦,正则表达式支持字符重复表示的形式,语法如下:

{n, m}:匹配前一项至少n次,但不能超过m次{n, }:匹配前一项n次或者更多次{n}:匹配前一项n次?:匹配前一项0次或者1次+:匹配前一项1次或者多次*:匹配前一项0次或多次

例如:

/\d{2,4}/:匹配2~4个数字/\w{3}\d?/:精确匹配3个ASCII字符和1个可选的数字/\s+java\s+/:匹配前后带有一个或多个空格的字符串“java”/[^(]*/:匹配一个或多个非左括号的字符

上面列出的正则表达式的匹配重复字符是尽可能多地匹配,而且允许后续的正则表达式继续匹配,这种匹配模式为贪婪模式,当然也有非贪婪模式,即尽可能少地匹配,做法是在重复匹配字符的后面跟随一个问号。

例如:/a+/和/a+?/对于“aaa”来说,前者贪婪匹配三个字母,后者非贪婪只匹配第一个字母。使用非贪婪的匹配模式所得到的结果可能和期望不一致,如/a+b/和/a+?b/对于“aaab”来说,它们匹配的都是整个字符串,前者贪婪模式无可置疑,但后者非贪婪模式怎么会如此呢,这是因为正则表达式的模式匹配总是会寻找字符串中第一个可能匹配的位置,由于该匹配是从字符串的第一个字符开始的,因此在这里不考虑它的子串中更短的匹配。

正则表达式的语法还包括指定选择项、子表达式分组和引用前一子表达式的特殊字符,如下所示:

|:选择,匹配的是该符号左边的子表达式或右边的子表达式(...):组合,将几个项组合为一个单元,这个单元可通过“*”、“+”、“?”和“|”等符号加以修饰,而且可以记住和这个组合相匹配的字符串以供此后的引用使用。(?:...):只组合,把项组合到一个单元,但不记忆与该组相匹配的字符。\n:和第n个分组第一次匹配的字符相匹配,组是圆括号内的子表达式,也有可能是嵌套的,组索引是从左到右的左括号数,“(?:”形式的分组不进行数字编码。

例如:

/ab|cd|ef/:表示可以匹配字符串ab,也可以匹配字符串cd,还可以匹配字符串ef。/\d{3}|[a-z]{4}/:表示匹配的是三位数字或者四个小写字母。/a|ab/:对于字符串“ab”,只匹配a而不是全部的ab,因为选择项从左到右开始匹配,直到发现了匹配,如果左边的选择项匹配成功,就忽略右边的匹配项,即使右边的匹配项产生更好的匹配结果。/java(script)?/:可以匹配字符串java,其后可以有script也可以没有,使用了圆括号分组。/(ab|cd)+|ef/:可以匹配字符串ef,也可以匹配字符串ab或cd的一次或多次重复。/([Jj]ava([Ss]cript)?)\sis\s(fun\w*)/:嵌套形式,其中([Ss]cript)?)可以用\2代替。/([Jj]ava(?:[Ss]cript)?)\sis\s(fun\w*)/:嵌套形式,其中(?:[Ss]cript)?)仅仅用于分组,\2引用的变成了(fun\w*)。/([‘ “])[^‘ “]*\1/:字符串两端是一对单引号或者双引号,中间是任意个非单、双引号的字符,如果写成/([‘ “])[^‘ “]*[‘ “]/是不合逻辑的,因为字符串两端无法保证单、双引号的配对。

正则表达式还可以指定匹配位置,如下所示:

^:匹配字符串的开头,在多行检索时,匹配一行的开头。$:匹配字符串的结尾,在多行检索时,匹配一行的结尾。\b:匹配一个单词的边界。\B:匹配非单词边界的位置。(?=p):零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符,并不是真正意义上的匹配。(?!p):零宽负向先行断言,要求接下来的字符不与p匹配。

例如:

/^JavaScript$/:匹配单词JavaScript。/\bJava\b/:匹配单词Java本身。/\B[Ss]cript/:与JavaScript和postscript匹配,但不与script和Scripting匹配。/[Jj]ava([Ss]cript)?(?=\:)/:可以匹配“JavaScript: The Definition Guide”中的“JavaScript”,但是不能匹配“Java in a Nutshell”中的“Java”,因为后者没有冒号。/Java(?!Script)([A-Z]\w*)/:可以匹配Java后跟随一个大写字母和任意多个ASCII字符,但Java后面不能跟随Script。

正则表达式还可以指定修饰符,修饰符是放在第二个“/”的后面,有三个修饰符。

i:执行不区分大小写的匹配。g:执行一个全局匹配,即找到所有的匹配,而不是在找到第一个就停止。m:多行模式匹配,^匹配一行的开头和字符串的开头,$匹配行的结尾和字符串的结尾。

例如:

/java$/im:可以匹配“java”,也可以匹配“Java\nis fun”。/\bjava\b/gi:不区分大小写匹配所有单词“java”。

通过String使用正则表达式——

上面介绍了那么多正则表达式的语法,那么怎么来使用它们呢?String对象提供了4种方法:search()、replace()、match()和split(),它们功能不同,各有特色,详细用法可查看String对象,下面只介绍replace()的一种有趣的用法。

var quote = /``([^``]*)``/g;text.replace(quote, ‘ “$1” ‘);

上面的replace()用法中,关键的地方在于$1,它只是用中文半角引号’’替换英文引号“,引号之间的内容保持不变。

通过RegExp对象使用正则表达式——

RegExp对象的构造函数带有两个参数,第一个参数是正则表达式,也就是正则表达式直接常量两个斜线之间的部分,但是要用“\”字符作为转义字符的前缀,第二个参数是可选的修饰符,如下例子所示:

var zipcode = new RegExp(“\\d{5}”, “g”);

使用RegExp的好处之一就是可以动态创建正则表达式,而不必像直接常量那样写死在代码中,灵活性更强。

RegExp对象包含5个属性:source,只读字符串,正则表达式文本;global,只读布尔值,说明正则表达式是否带有修饰符g;ignoreCase,只读布尔值,说明正则表达式是否带有修饰符i;multiline,只读布尔值,说明正则表达式是否带有修饰符m;lastIndex,可读可写整数,如果匹配模式带有g修饰符,这个属性存储在整个字符串中下一次检索的开始位置。

RegExp对象包含2个方法,exec()test()。前者类似于String.match(),参数为一个字符串,匹配失败返回null,成功匹配时返回数组,并提供关于本次匹配的完整信息。后者则较为简单,参数也是一个字符串,如果包含正则表达式的一个匹配结果,则返回true。

1 0
原创粉丝点击