JavaScript权威指南(10)——正则表达式的模式匹配

373 阅读3分钟

正则表达式的定义

  1. 字符直接量var pattern = /s$/
  2. 构造函数RegExp()
  3. ES 5规定同一段代码所表示的正则表达式直接量的每次运算返回新对象,ES 3返回同一个对象
  4. 直接量字符

  1. 字符类

  1. 重复

/\d{2,4}/ // Match between two and four digits
/\w{3}\d?/ // Match exactly three word characters and an optional digit
/\s+java\s+/ // Match "java" with one or more spaces before and after
/[^(]*/ // Match zero or more characters that are not open parenthesis
  1. 非贪婪的重复——在待匹配的字符后跟随一个问好即可
   使用“aaa”作为匹配字符串,/a+/会匹配三个字符
   /a+?/会匹配一个字符
  1. 选择、分组和引用
   /ab|cd|ef/可以匹配字符串ab,cd,或者ef
   /\d{3}|[a-z]{4}/可以匹配三位数字或四个小写字母

圆括号的一个作用是把单独的项组合成子表达式

   /java(script)?/可以匹配java,其后可以有script或没有
   /(ab|cd)+|ef/可以匹配ef,也可以匹配ab或cd的一次货多次重复

圆括号的另一个作用是在完整的模式中定义字模式

   /[a-z]+(\d+)/可以从匹配中抽取数字

圆括号的另一个用途是允许在同一正则表达式的后部引用前面的子表达式

   /([Jj]ava([Ss]cript)?)\sis\s(fun\w*)/
   其中的([Ss]cript)可以用\2来指代
   /['"][^'"]*['"]/不要求左侧和右侧的引号
   /(['"])[^'"]*\1/匹配左侧和右侧的引号

在正则表达式中不用创建带数字编码的引用,以(?:和)来进行分组

   /([Jj]ava(?:[Ss]cript)?)\sis\s(fun\w*)/
   \2指代(fun\W*)

  1. 指定匹配位置
   /^JavaScript$/匹配单词JavaScript
   /\sJava\s/匹配前后有空格的单词Java(如果在开始或结尾,则匹配不成功)
   /\bJava\b/匹配单词Java,返回值无空白符——\b是单词的边界
   \B把匹配的锚点定位在不是单词的边界处
   /\B[Ss]cript/与JavaScript和postscript匹配
   如果在符号(?=和)之间加入一个表达式,就是一个先行断言,圆括号中的表达式必须正确匹配
   如/[Jj]ava([Ss]cript)?(?=\:)/可以匹配JavaScript:The 中的JavaScript,不能匹配Java in。。
   (?!的断言是负向先行断言,用以指定接下来的字符都不必匹配
   如/Java(?! Script)([A-Z]\w*)/可以匹配Java后跟随一个大写字母和任意多个ASCII单词,Java后面不能跟随Script

  1. 修饰符

    /\bjava\b/i不区分大小写
    /\bjava\b/gi找到所有的匹配
    

用于模式匹配的string方法

  1. search(),参数是一个正则表达式,返回第一个与之匹配的字串的起始位置,否则返回-1
   "JavaScipt".search(/script/i)
   search会将参数转换成正则表达式
   search不支持全局搜索
  1. replace(),第一个参数是正则表达式,第二个参数是要进行替换的字符串
   text.replace(/javascript/gi,"JavaScript")
   支持g全局替换所有匹配的字符串
   如果第一个参数是字符串,会直接搜索这个字符串,不会转换成RegExp()
   正则表达式使用圆括号括起来的子表达式是带有从左到右的索引编号,如果替换字符串中出现了$加数字,那么会与指定的子表达式相匹配的文本来替换这两个字符
   
   // 引号开始,引号结束,中间无引号
   var quote = /"([^"]*)"/g;
   // 将字符串中的引文引号替换为中文半角引号
   text.replace(quote, '“$1”');
  1. match(),参数是正则表达式,返回一个由匹配结果组成的数组,如果设置了g,则返回所有匹配结果
   "1 plus 2 equals 3".match(/\d+/g)  //返回["1","2","3"]

即使不是全局检索,返回也是数组,此时第一个元素是完整的匹配,其他元素存储的是使用圆括号括起来的表达式相匹配的子串

   var url = /(\w+):\/\/([\w.]+)\/(\S*)/;
   var text = "Visit my blog at http://www.example.com/~david";
   var result = text.match(url);
   if (result != null) {
       var fullurl = result[0]; // Contains "http://www.example.com/~david"
       var protocol = result[1]; // Contains "http"
       var host = result[2]; // Contains "www.example.com"
       var path = result[3]; // Contains "~david"
   }
  1. split(),参数表示分隔符
   "123,456,789".split(","); // Returns ["123","456","789"]

参数也可以是正则表达式

   "1, 2, 3, 4, 5".split(/\s*,\s*/); // Returns ["1","2","3","4","5"]

RegExp对象

  1. 第一个参数是正则表达式(\需要替换成\\),第二个参数是修饰符g,i,m或它们的组合
   var zipcode = new RegExp("\\d{5}", "g");
  1. RegExp包含5个属性

    source——包含正则表达式的文本

    global——是否带有修饰符g

    ignoreCase——是否带修饰符i

    multiline——是否带修饰符m

    lastIndex——如果带g,这个属性存储整个字符串中下一次检索的开始位置

  2. exec(),执行正则表达式进行匹配

    var pattern = /Java/g;
    var text = "JavaScript is more fun than Java!";
    var result;
    while((result = pattern.exec(text)) != null) {
        alert("Matched '" + result[0] + "'" +
        	" at position " + result.index +
        	"; next search begins at " + pattern.lastIndex);
    }
    
  3. test(),检测字符串

   var pattern = /java/i;
   pattern.test("JavaScript"); // Returns true