zoukankan      html  css  js  c++  java
  • JavaScript中的正则表达式

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


     定义

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

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

    直接量字符

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

    字符类

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

    例如 [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]
    [] 退格直接量(特例)

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

    重复

    语法见下表:

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

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

    选择、分组和引用

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

    三个作用:

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

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

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

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

    指定匹配位置

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

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

    几个例子:

    匹配单词JavaScript,使用 /^JavaScript$/ 
    匹配Java单词本身,需要使用 /Java/ 
    /[Jj]ava([Ss]cript)?(?=:)/ 能匹配JavaScript:The Definitive Guid,不能匹配Java is中的java。
    /Java(?!Script)(A-Zw*)/ 可以匹配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(/w+/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。

  • 相关阅读:
    实现自己的Linq to Sql
    [分享] 浅谈项目需求变更管理
    【分享】老程序员的经验和价值在哪里?
    程序员是自己心中的“上帝”
    [分享]解析“程序员的十大技术烦恼”
    【分享】帮助你早些明白一些道理
    “风雨20年”的20条精辟编程经验
    【分享】 优秀程序员的代码是“活的”
    给开发人员培训时的语录
    【分享】SQL Server优化50法
  • 原文地址:https://www.cnblogs.com/OldZhao/p/5056643.html
Copyright © 2011-2022 走看看