JavaScript中的正则表达式

以下内容是来自《JavaScript权威指南(第六版)》正则表达式的模式匹配章节的笔记。


 定义

JavaScript中的正则表达式定义有两种方式:

  1.  var pattern = /s$/;  或者
  2.  var pattern = new RegExp('s$'); 

直接量字符

  1. 所有字母和数字都是按照字面含义进行匹配
  2. 非字母的字符匹配,使用反斜线  \  。如下表
字符匹配
字母和数字字符 自身
\o NUL字符(\u0000)
\t 制表符(\u0009)
\n 换行符(\u000A)
\v 垂直制表符(\u000B)
\f 换页符(\u000C)
\r 回车符(\u000D)
\xnn 由十六进制数nn指定的拉丁字符,例如\x0A等价于\n
\uxxxx 由十六进制数xxxx指定的Unicode字符,例如\u0009等价于\t
\cX 控制字符^X,例如,\cJ等价于换行符\n

字符类

将直接量字符单独放进方括号内就组成了字符类

例如 [abc] 匹配a或者b或者c

可以使用 ^  表示否定
可以使用连字符表示范围 [a-zA-Z0-9] 

某些字符很常用,所以用简练的方式来表示,下表:

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

注:\b有特殊的含义,见下文,若要表示退格直接量,需要中括号。[\b]

重复

语法见下表:

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

非贪婪的重复
上表列出的匹配重复字符是尽可能多的匹配,而且允许后续的正则表达式继续匹配,因此我们称之为贪婪的。若要进行非贪婪的匹配,只需在带匹配的字符后面跟一个问号 ?    即可: ?? 、 +? 等等。

选择、分组和引用

  • 字符|用来分割供选择的字符,类似于或。注:选择项的尝试匹配顺序是从左到右,直到发现了匹配项。如果左边的选择项匹配,就忽略后边的匹配项,即使有更好的匹配
  • 分组引用使用圆括号()

三个作用:

  • 把单独的项组合成表达式,以便可以像处理一个独立单元那样使用 | * + ? 等对单元内的项进行处理。

  • 在完整的模式中定义子模式。当一个正则表达式成功与目标字符串匹配时,可以从目标串中抽出与圆括号中子模式匹配的部分。(书中后续有详解)

  • 允许在同一正则表达式的后部引用前面的子表达式。通过字符 \ 后加一位或多位数字实现的,数字代表了子表达式在正则表达式中的位置。例如: /([Jj]ava([Ss]cript)?)\sis\s(fun\w*)/  中的  ([Ss]cript)  就可以用  \2 指代。

注: 对正则表达式字表达式的引用,不是针对子表达式模式的引用,而是指与那个模式相匹配的文本的引用,这样,引用可以用于实施一条约束,即一个字符串各个单独部分包含的是完全相同的字符,例如:
/['"][^'"]*['"]/ 匹配的是位于单引号或者双引号之间的0个或多个非引号字符,但是他不能让作用两端的引号匹配,可以改成这样  /(['"])[^'"]*\1/ ,但如果这样写  /(['"])[^\1]*\1/ 就是错误的,正则表达式不允许双引号内有单引号,反之亦然。
检索和替换强烈依赖此特性。

指定匹配位置

这些能匹配位置的字符也被称为正则表达式的锚。如下表:

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

几个例子:

匹配单词JavaScript,使用 /^JavaScript$/ 
匹配Java单词本身,需要使用 /\bJava\b/ 
/[Jj]ava([Ss]cript)?(?=\:)/ 能匹配JavaScript:The Definitive Guid,不能匹配Java is中的java。
/Java(?!Script)(A-Z\w*)/ 可以匹配JavaBeans但不能匹配JavaScript。

修饰符

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

 


用于模式匹配的String方法

search()方法

参数是一个正则表达式,返回第一个与之匹配的字串的起始位置,如果找不到匹配的字串,它将返回-1。比如:'JavaScript'.search(/script/i) 返回4。

同时,search方法不支持全局搜索,因为它会忽略正则表达式中的修饰符g。

replace()方法

执行检索和替换的功能。第一个参数是正则表达式,第二个参数是要进行替换的字符串。

如果指定了修饰符g,则会替换所有的匹配项,否则只替换第一个。

另外,上一篇文章中提到,正则表达式使用圆括号进行分组,同时这些括起来的内容从左到右是有索引编号的。如果在替换字符串中出现了$加数字,那么replace()将用与指定的字表达式相匹配的文本来替换这两个字符。比如:

var quote = /"([^"]*)"/g;
'abc"xxx"def'.replace(quote, '“$1”');//abc“xxx”def

此外,replace第二个参数还可以是函数。例如:

text.replace(/\b\w+\b/g, function(word) {
  return word.substring(0,1).toUpperCase + word.substring(1);
})

match()方法

唯一参数就是正则表达式,返回一个由匹配项组成的数组。若设置了g则返回所有匹配项组成的数组。

另外,如果没有修饰符g,返回的数组中第一项是匹配的字符串,后面的项是正则表达式中圆括号括起来的项。

比如:

var url = /(\w+):\/\/([\w.]+)\/(\S*)/;
var text = 'Visit my blog http://www.example.com/~david'; //['http://www.example.com/~david', 'http', 'www.example.com', '~david']

split()方法

split的参数也支持正则表达式。

RegExp对象

  • RegExp的五个属性

  source:正则表达式的文本
  global:是否有修饰符g
  ignoreCase:是否有修饰符i
  multiline:是否有修饰符multiline
  lastIndex:如果有修饰符g,这个属性存储下一次开始检索的位置。

  • 两个方法

  exec()方法,与match类似,但总是返回一个结果,并返回lastIndex属性的信息。从而可以反复调用exec方法获得所有匹配。

  test()方法,比exec更简单一些,如果包含匹配结果则返回true。

 

posted @ 2015-03-14 20:49  zjzhome  阅读(212)  评论(0编辑  收藏  举报