闵超的主页

JavaScript正则表达式的模式匹配

2016-04-05
闵超

JavaScript正则表达式的模式匹配

正则表达式(regular expression)是一个描述字符模式的对象。JavaScript的RegExp表示正则表达式,String和RegExp都定义了方法,后者使用正则进行强大的模式匹配和文本检索与替换功能。JavaScript的正则表达式语法是Perl5的正则表达式语法的大型子集,所以对于有Perl编程经验人来说,学习JavaScript的正则表达式是很简单的。

正则表达式的定义

JavaScript中正则表达式用RegExp对象表示,可以使用RegExp()构造函数来创建RegExp对象。不过RegExp对象更多的是通过一种特殊的直接量语法来创建。

就像通过引号包裹字符的方式来定义字符串直接量一样,正则表达式直接量定义为包含在一对斜杠(/)之间的字符。

例如:var  pattern = /s$/;

RegExp直接量和对象的创建

就像字符串和数字一样,程序中每个取值相同的原始类型直接量均表示相同的值,这是显而易见的。程序运行每次遇到对象直接量(初始化表达式)诸如{}和[]的时候都会创建新对象。比如,若果在循环体中写var a=[],则每次遍历都会创建一个新的空数组。

正则表达式直接量则与此不同,ECMS3规范规定,一个正则表达式直接量会在执行到它时转换一个未RegExp对象,同一段代码所表示正则表达式直接量的每次运算都返回同一个对象。ECMS5规范则做了相反的规定,同一段代码所表示的正则表达式直接量的每次运算都返回新对象。IE一直都是按照ECMS5规范实现的,多数最新版本的浏览器也开始遵循ECMS5,尽管目前该标准并未全面广泛推行。

直接量字符

正则表达式中的所有字母和数字都是按照字面含义进行匹配的。JS正则表达式语法也支持非字母字符匹配,这些字符需要通过反斜杠()作为前缀进行转义。

字符				匹配
字母和数字字符		本身

\o			NUL字符(\u0000)
\n			换行符(\u000A)
\t			制表符(\u0009)
\v			垂直制表符(\u00B)
\f			换页符(\u000C)
\r			回车符(\u000D)
\xnn		由十六进制nn指定的拉丁字符如\xOA=\n
\uxxx		由十六进制指定Unicode字符,如\u0009=\t
\cX			控制字符^X,例如,\cJ=换行符\n

在正则表达式中,许多标点符号具有特殊含义,它们是:

^ $ . * + ? = ! : | \ / ( ) [ ] { }

如果想在正则表达式中使用这些字符的直接量进行匹配,则必须使用前缀\,这是一条通行规则。 如果不记得哪些标点符号需要反斜线转义,可以在每个标点符号前都加上反斜杠。另外,需要注意,许多字母和数字在有反斜线做前缀是也有特殊含义,所以对于想按照直接量进行匹配反斜线本身,则必须使用反斜线来将其转义。

字符类

将直接量字符单独放进方括号内就组成了字符类。一个字符类可以匹配它所有包含的任意字符。正则表达式/[abc]/就和字母”a”、”b”、”c”中任意一个都匹配,另外,通过”^”来定义否定字符类,它匹配所有不包含在方括号内的字符。

正则表达式字符类

字符		匹配
[…]		方括号内的任意字符
[^…]	不在方括号内的任意字符
.		除换行符和
\w		任何ASCEII字符组成的单词等价于[a-zA-Z0-9]
\W		任何不是ASCII字符组成的单词,等价于[^a-Za-z-0-9]
\s		任何Unicode空白符
\S		任何非Unicode空白符的字符,注意\W和\S不同
\d		任何ASCII数字,等价于[0-9]
\D		除了ASCII数字之外的任何字符,等价于[^0-9]
[\b]	退格直接量(特例)

注意,在方括号之内也可以写这些特殊转义字符,比如\s匹配所有的空白字符,\d匹配所有的数字,因此/[\s\d]/就匹配任意空白字符或者数字。

重复

可以把两位数描述成/\d\d/,四位数描述成/\d\d\d\d/。我们在正则模式之后跟随用以指定字符重复的标记。 正则表达式的重复字符语法

字符		含义
{n,m}	匹配前一项至少n次,但不能超过m次
{n,}	匹配前一项n次或者更多次
{n}		匹配前一项n次
?		匹配前一项0次或者1次,也就是说前一项是可选的,等价于{0,1}
+		匹配钱一项一次或多次,等价于{1,}
*		匹配前一项0次或多次,等价于{01}

例子:

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

非贪婪的重复

上面列出的匹配重复字符是尽可能多地匹配,而且允许后续的正则表达式继续匹配。因此,我们称之为”贪婪的”匹配。

我们同样可以使用正则表达式进行非贪婪匹配。 只需在待匹配的字符后面跟随一个问号即可:”??”、”?+”、”*?”或”{1,5}?”。比如,正则表达式/a+/可以匹配一个或多个连续的字母a。

选择、分组和引用

正则表达式的语法还包括指定选择项、子表达式分组和引用前一子表达式的特殊字符。字符” ”用于分隔供选择的字符。
字符		含义
|		选择,匹配的是该符号左边的子表达式或右边的子表达式
(…)		组合,将几个项组合为一个单元,这个单元可通过”*”、”+”、”?”和”|”等等符号加以修饰,
		而且可以记住和这个组合匹配的字符串以供此后的引用使用

(?:…)	只组合,把项组合到一个单元,但不记忆与该组合相匹配的字符
\n		和第n个分组第一次匹配的字符相匹配,组是圆括号中的子表达式(也有可能是嵌套的),
		组索引是从左到右的左括号数,”(?:”形式的分组不编码

指定匹配位置

正如前面所介绍的,正则表达式中的多个元素才能够匹配字符串的一个字符。例如,\s匹配的只是一个空白符。

正则表达式中的锚字符

字符			含义
^			匹配字符串的开头,在多行检索中,匹配一行的开头
$			匹配字符串的结尾,在多行检索中,匹配一行的结尾
\b			匹配一个单词的边界,简言之,就是位于字符\w和\W之间的位置,
			或位于字符\w和字符串的结尾或开头之间的位置(但需要注意,[\b]匹配的是退格符)
\B			匹配非单词边界的位置
(?=p)		零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符
(?!p)		零宽负向先行断言,要求接下来的字符不与p匹配

修饰符

正则表达式中的语法还有最后一个知识点,即正则表达式的修饰符,用以说明高级匹配模式的规则。

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

RegExp对象

正则表达式是通过RegExp对象来表示的。除了RegExp()构造函数之外,RegExp对象还支持三个方法和一些属性。接下来的两节会对RegEep模式匹配方法和属性展开讲述。

//全局匹配字符串中的5个数字,注意这里使用了”\”,而不是”\”

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

RegExp的属性

每个RegExp对象都包含5个属性。属性source是一个只读的字符串,包含正则表达式的文本。属性global是一个只读的布尔值,用以说明这个正则表达式是否带有修饰符g。

RegExp的方法

RegExp对象定义了两个用于执行模式匹配操作的方法。它们的行为和上文介绍过的String方法很类似。

RegExp最主要的执行模式匹配的方法是exec(),它与10.2节介绍过的String方法match()相似,只是RegExp方法的参数是一个字符串,而String方法的参数是一个RegExp对象。

exec()方法对一个指定的字符串执行一个正则表达式,简言之,就是在一个字符串中执行匹配检索。


相似文章

Content

如果喜欢,打个赏,加个好友吧

扫描二维码打赏

扫描二维码打赏