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

    一、基本使用

    在 JavaScript 中,可以用下面的两种方法来创建一个正则表达式(RegExp)对象:

    var re = /fox/;
    var re = new RegExp("fox");
    

    创建了 RegExp 对象后,就可以用 test() 方法来检测某个字符串是否匹配。例如:

    var re = /fox/;
    var str = "The quick brown fox jumps over the lazy dog";
    alert(re.test(str)); // true 
    

    test() 方法根据字符串是否匹配该正则表达式,返回 true 或者 false。

    RegExp 对象还有另一个参数,用于指明匹配标志。该参数是字母 g, i 和 m 的任意组合。其中 g 表示全局模式,即查找全部匹配的子串;i 表示不区分大小写;m 表示多行模式,即让 ^ 和 $ 符也分别匹配行首和行尾(见下面的介绍)。例如

    var re = /fox/gi;
    var re = new RegExp("fox", "gi");
    

    二、选择符 |

    如果我们要匹配 cat 或者 dog,可以用选择符 |。例如:

    var re = /cat|dog/;
    var str = "The quick brown fox jumps over the lazy dog";
    alert(re.test(str)); // true 
    

    三、字符集 [] 

    如果我们需要匹配某些字符,可以用字符集符号 []。比如 [aeiou] 匹配 5 种元音字母。再如下面的例子:

    var re = /f[aeiou]x/;
    var str = "The quick brown fox jumps over the lazy dog";
    alert(re.test(str)); // true
    

    由于字符串中包含 fox,所以匹配成功。如果我们需要匹配小写字母,不用一一列出,用 [a-z] 这种简写方式就可以了。类似地,[0-9] 匹配10个数字符号。相反地,如果要匹配非元音字母,可以用 [^aeiou]。方括号内部最前面的 ^ 符号表示补集。

    同时,对常用的字符集,我们也有下面这些简记方式:

    \0 匹配 NUL 字符
    \b 匹配位于单词的开头或结尾的位置
    \B 匹配不处在单词的开头或结尾的位置
    \d 匹配数字字符,等同于 [0-9]
    \D 匹配非数字字符,等同于 [^0-9]
    \f 匹配换页符
    \n 匹配换行符
    \r 匹配回车符
    \s 匹配 Unicode 空白字符,即 [\f\n\r\t\v \u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u205f\u3000\ufeff]
    \S 匹配非 Unicode 空白字符,即 [^\f\n\r\t\v \u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u205f\u3000\ufeff]
    \t 匹配制表符
    \v 匹配垂直制表符
    \w 匹配单词字符,等同于 [a-zA-Z0-9_]
    \W 匹配非单词字符,等同于 [^a-zA-Z0-9_]
    . 匹配单个字符,除了换行符和 Unicode 行终止符,即 [^\n\r\u2028\u2029]

    其中 \s \S . 这几个字符集,可能不同的浏览器的实现不一样。

    四、重复符 ? * +

    如果需要匹配某些重复的字符,可以在该字符后面加上重复符 ?*+。其中 ? 表示重复 0 次或 1 次,* 表示重复 0 次或多次,+ 表示重复 1 次或多次。例如:

    var re1 = /9?/;
    var re2 = /9*/;
    var re3 = /9+/;
    var str = "The quick brown fox jumps over the lazy dog";
    alert(re1.test(str)); // true
    alert(re2.test(str)); // true
    alert(re3.test(str)); // false

    类似地,{2,} 表示匹配 2 次或以上,而 {2,5} 表示匹配至少 2 次而且至多 5 次。

    五、非贪婪匹配

    前面的 * 和 ? 的贪婪匹配的重复符,而 *? 和 +? 是对应的非贪婪匹配的重复符。贪婪匹配将得到最长的匹配,而非贪婪匹配将得到最短的匹配。例如:

    /-.+-/.exec("-ab-cd-e")    // -ab-cd-
    /-.+?-/.exec("-ab-cd-e")   // -ab-  

    六、字符串开头和结束

    使用 ^$,可以分别匹配字符串开头和结束的位置。例如:/^[1-9]\d*$/ 匹配一个正整数。如果该正则表达式有 m 标志,则它们也可以分别匹配行首和行尾。此时,字符串的各行由 \r\n 分割。

    七、捕获组和非捕获组

    (x) 包含的内容为一个捕获组,而用 (?:x) 包含的内容为一个非捕获组。捕获组的内容将出现在 re.exec(str)str.search(re) 函数的返回值里面。另外,我们可以用 \1\2 分别引用前面的第 1 个,第 2 个捕获组的内容,等。这些捕获组按照左括号出现的顺序编号。

    八、向前查找

    x(?=y) 表示当 x 在 y 之前时匹配 x,而 x(?!y) 当 x 不在 y 之前时匹配 x。对这两种情形,y 都不包含在匹配的字符串中。例如:

    /-\w+(?!-)/.exec("a-bcd-") // 'bc'

    九、特殊字符

    在正则表达式中,( ) [ ] { } \ ^ $ . | ? * + 这 14 个字符是特殊字符,要匹配这些字符,必须在它们前面用反斜杠 \ 进行转义。

    十、相关函数列表

    与正则表达式相关的函数主要在 RegExp 对象和 String 对象中,包括下面这些函数。

    re.test(str) 和 str.search(re):判断字符串和正则表达式是否匹配,前者返回值为 true 或者 false,后者返回值为匹配子串的起始位置。

    re.exec(str) 和 str.match(re): 查找字符串中和正则表达式匹配的子字符串。

    如果正则表达式中没有 g 标志,两者的返回值是一样的:匹配成功返回值为数组,这个数组的第一项为所匹配的子字符串,后面各项为各个捕获组的内容;返回的数组中还包含两个属性 index 和 input,分别表示所匹配的位置和输入字符串;匹配失败返回值为 null。

    如果正则表达式中有 g 标志,两者的返回值不一样:前者的返回值和不含 g 标志时类似,但此时正则表达式 re 中多了一个 lastIndex 属性,指明下次搜索的开始位置,如果匹配不成功则 lastIndex 属性被重置为 0。而后者的返回值包含所有匹配的子字符串,而且不再有 index 和 input 属性。

    如果我们需要得到所有匹配的字符串的位置,只能用 re.exec(str)。例如:

    var re = /(\n|\r\n){2,}/g;
    var str = "ab\n\ncd\n\n\nef";
    var result, i = 0, msg;
    while ((result = re.exec(str)) !== null) {
      msg = "Found a paragraph at " + i + '-' + result.index + ". ";
      msg += "Next match starts at " + re.lastIndex; 
      console.log(msg);
      i = re.lastIndex;
    }
    if (i < str.length) {
      console.log("Found a paragraph at " + i + '-' + str.length + ".");
    }
    // Found a paragraph at 0-2. Next match starts at 4
    // Found a paragraph at 4-6. Next match starts at 9
    // Found a paragraph at 9-11.
    

    str.replace(re, newstr):将 str 中与正则表达式匹配的子字符串替换为 newstr。默认只替换一次,如果要替换多次需要在正则表达式中加上 g 标志。例如:

    var str = 'one apple and two apples';
    var re1 = /apple/, re2 = /apple/g;
    var newstr = 'banana';
    console.log(str.replace(re1, newstr));
    // one banana and two apples
    console.log(str.replace(re2, newstr));
    // one banana and two bananas
    

    另外,在 replace 的第二个参数 newstr 中,$ 字符有如下特殊含义(因此 newstr 包含 $ 时需要小心):

    • $& :表示所匹配的子字符串
    • $`:表示所匹配的子字符串之前的字符串
    • $' :表示所匹配的子字符串之后的字符串
    • $n 或 $nn:表示第 n 或 nn 个捕获组的内容
    • $$ :表示字符 $

    这个 replace 方法的第二个参数也可以是一个函数,即 str.replace(re, func)。此时替换函数 func 的参数中,第一个为所匹配的子字符串,接下来为各个捕获组的内容;接下来是匹配子串的起始位置,最后一个参数是所查找的字符串。该替换函数的返回值将作为替换的内容。例如:

    text.replace(/[<>\&\"\']/g, function(c) {
        return '&#' + c.charCodeAt(0) + ';';
    });
    

    这个例子中,我们将 HTML 的预留字符替换成它的字符实体。

    参考资料:

    [1] RegExp - JavaScript | MDN
    [2] test - JavaScript | MDN
    [3] exec - JavaScript | MDN
    [4] String.match - JavaScript | MDN
    [5] search - JavaScript | MDN
    [6] replace - JavaScript | MDN
    [7] JavaScript RegExp 对象参考手册
    [8] Online RegExp Tester (1) (2)
    [9] javascript之正则表达式 (一) (二)
    [A] 深入浅出之正则表达式 (一) (二)
    [B] JavaScript, Regex, and Unicode
    [C] JavaScript Regex and Unicode Tests

    [YAML] Updated: 2014-01-12 10:23:00

  • 相关阅读:
    光遇————墓土(补充)蜡烛收集
    光遇————雨林
    每日光遇日记
    光遇————墓土
    光遇————云野超级不详细的蜡烛收集
    光遇————晨岛超级详细的蜡烛收集
    高精度
    HDU 1002: A + B Problem II (大数加法)
    HDU 1018:Big Number (位数递推公式)
    D2. Remove the Substring (hard version) (KMP-next数组 ) ( Codeforces Round #579 (Div. 3) )
  • 原文地址:https://www.cnblogs.com/zoho/p/2872966.html
Copyright © 2011-2022 走看看