JavaScript中一个经典的正则例子

Posted on

学习知识的最好方法就是看例子.(个人观点) 因为书上总是会把概念和公式讲的晦涩难懂,才显得作者高大上.所以我总是喜欢 通过例子学习知识.每次写正则的时候总是喜欢查看例子学习如何使用,因为正则实在太耗脑细胞了,记不住,也没必要记住.学会 如何使用并在项目中熟练运用就好了,经常使用的话也就自然记住了.

JavaScript语言精粹上面有个非常棒的学习例子,每次写正则的时候都会想起它.所以还是记一下分享给大家也方面我查询啦~

    var parse_url=/^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
    var url="http://www.ora.com:80/goodparts?q#fragment";
    var result=parse_url.exec(url);
    var names=['url','scheme','slash','host','port','path','query','hash'];
    var blanks='     ';
    var i;
    for(i=0;i<names.length;i+=1){
        console.log(names[i]+ ':' +blanks.substring(names[i].length),result[i]);
    }

让我们分解parse_url的各个部分,看看它是如何工作的:

^

^字符表示此字符串的开始.它是一个锚,指引exec不要跳过那些不像URL(non-URL-like)的前缀,只匹配那些从开头就像URL一样的字符串:

(?:([A-Za-z]+):)?

这个因子匹配一个协议名,但仅当它后面跟随一个:(冒号)的时候才匹配.(?:...)表示一个非捕获型分组(noncapturing group). 后缀 ? 表示这个分组是可选的. 问号表示重复0次或一次.(...)表示一个捕获型分组(capturing group).一个捕获型分组会复制它 所匹配的文本,并把其放到result数组里.每个捕获型分组都会被指定一个编号.第一个捕获型分组的编号是1,所以该分组所匹配的文本副本 会出现在result[1]中.[...]表示一个字符类,A-Za-z这个字符类包含26个大写字母和26个小写字母.连字符( - )表示范围从 A 到 Z. 后缀 + 表示这个字符类会被匹配一次或者多次.这个组后面跟着字符:,它会按字面进行匹配:

(\/{0,3})

下一个因子是捕获型分组2.\/表示该匹配/(斜扛).它是\(反斜杠)来进行转义,这样它就不会被错误地解释为这个正则表达式的结束符.后缀{0,3}表示 / 会被匹配0次,或者或者1~3次:

([0-9.\-A-Za-z]+)

下一个因子是捕获型分组3.它会匹配一个主机名,由一个或多个数字、字母,以及 . 或 - 字符组成. - 会被转义为 \- 以防止与表示范围的连字符想混淆:

(?::(\d+))?

下一个可选的因子匹配端口号,它是由一个前置 : 加上一个或多个数字而组成的序列. \d 表示一个数字字符.一个或多个数字组成的数字串会被捕获型 分组4捕获:

(?:\/([^?#]*))?

接下来是另一个可选的分组.该分组以一个 / 开始.之后的字符类[^?#]以一个 ^ 开始,它表示这个类包含除了?和#之外的所有字符.*表示这个字符类 会被匹配0次或多次.

注意这里的处理是不严谨的.这个类匹配除?和#之外的所有字符,其中包括了行结束符、控制字符,以及其他大量不应在此被匹配的字符.大多数情况下,它会按照 我们的预期去做,但某些恶意文本可能会有渗透进来的风险.不严谨的正则表达式是一个常见的安全漏洞发源地.写不严谨的正则表达式比写严谨的 正则表达式要容易得多.

(?:\?([^#]*))?

接下来,还有一个以一个 ? 开始的可选分组.它包含捕获型分组6,这个分组包含0个或多个非#字符.

(?:#(.*))?

最后一个可选分组是以 # 开始的 .会匹配除行结束符以外的所有字符.

$

$表示这个字符串的结束.它保证在这个URL的尾部没有其他更多内容了.