JavaScript中的正则表达式
前面说过正则表达式在不同语言平台只是存在一些书写或使用上的细微差别,所以对于JavaScript中的正则表达式无非就几个点需要熟悉一下。

JavaScript中正则表达式的定义
通过new RegExp对象产生,或者直接书写,因为JavaScript中用斜杠包围的式子被认为是正则表达式,所以可以方便地这样定义一个正则表达式: var regex = /\d+/;

涉及的标志
涉及的标志主要有:
(1)   i   :   忽略大小写
(2)   g  :   设置全局匹配
(3)   m :   设置多行匹配

以上标志可以搭配使用, 如全局匹配并忽略大小写可以写为:gi
m 标志比较特殊。m标志必须在字符串中含有换行(“\n”或者“\r\n”)并且正则表达式中含有 ^ (字符串开头标志)或者 $ (字符串结束标志)时才有用。通俗点说也就是 m 标志会将换行识别为一行的结束和另一行的开始,而这样识别的条件是字符串含有换行 且正则表达式为^$模式。

不要错误地理解多行匹配,实际上只要正则表达式不是 ^$ 模式的话本身就是支持多行的。比如以下代码, 换行形同摆设:
var str = "1aabb\n2aabb\n3aabb";
document.write(str.match(/\d/));       //输出   1a
document.write(str.match(/\d/g));      //输出    1a,  2a,  3a

RegExp对象的三个方法:
(1)compile():  编译正则表达式
(2)exec():  匹配字符串中匹配的值,返回找到的值,并确定其位置。
(3)test(): 检索字符串中指定的值。返回 true 或 false。

对于exec()方法,若正则表达式不带 g 标志,则无论执行多少次都只是匹配第一个结果。带上 g 标志则进行依次匹配,即第一次执行匹配第一个结果,第二次执行匹配第二个结果,依此类推。因此多次执行exec()方法一般都是带 g 标志的正则表达式(否则多次执行就没多大意义了)。并且,在得到匹配结果后,还能利用regexp的lastIndex获取当前匹配得到的结果的末尾位置。

对于test()方法,带不带 g 都是一样的,因为返回值为 boolean 类型,只要匹配就返回 true。

与正则表达式挂钩的自然就有String对象的方法:
(1)search():  检索与正则表达式相匹配的值。
(2)match():  找到一个或多个正则表达式的匹配。
(3)replace():  替换与正则表达式匹配的子串。
(4)split() : 把字符串分割为字符串数组。

对于search()方法,其不执行全局匹配,它将忽略标志 g。它同时忽略 regexp 的 lastIndex 属性,并且总是从字符串的开始进行检索,也就是说它总是返回 stringObject 的第一个匹配的位置。如果没有找到任何匹配的子串,则返回 -1。由于多匹配返回的是字符串数组,所以想要获取结果在原字符串中的位置利用match()是不太现实的,这里如果有位置方面的需求可以用RegExp的exec()方法。

对于match()方法,其可以匹配一个或多个结果,主要取决于regexp有没有全局匹配标志 g。若没有匹配到结果,方法返回 null。

对于replace()方法,其替换结果也是依赖于标志的,不带标志 g 的话只替换的一个匹配结果,带上 g 的话替换所以匹配的部分。

对于split()方法,g 标志有与没有是一样的。

下面是一个简单的demo,简要说明i,g,m标志的作用。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RegExpTest</title>
    <script type="text/javascript">
        function run() {
            var str = "year:2017 month:6 DAY:24";
            write("匹配对象: " + str + "<br/>");
            var result;

            var regexp = new RegExp(/[a-z]+/, 'gm');
            //var regexp1 = /[a-z]+/g;     //与上述写法等效
            /* 参数说明: g <----> 即global,全局匹配,会匹配出全部符合的结果
                         i <----> ignore case, 忽略大小写
                        gi <----> 上面两者组合 */

            write("<br/>exec()方法<br/>");
            write("g 和 gi 参数对比大小写忽略测试:<br/><strong>(/[a-z]+/g)</strong>:");
            while((result = regexp.exec(str)) !== null){
                write(result);
                write("   " + regexp.lastIndex + ",  ");  //匹配到的结果的尾部位置 比如 匹配到 year 位置为 4
            }

            var regexp2 = /[a-z]+/gi;
            write("<br/><strong>(/[a-z]+/gi)</strong>:");
            while((result = regexp2.exec(str)) !== null){
                write(result);
                write("   " + regexp2.lastIndex + ",  ");
            }


            write("<br/><br/>参数 g 效果展示:<br/>");
            write("(/\d+/g):");
            write(str.match(/\d+/g));   //带 g
            write("<br/>(/\\d+/):");
            write(str.match(/\d+/));    //不带 g
            write("<br/>不带全局属性 g 的只匹配第一个结果<br/><br/>");

            //字符串含有换行并且正则表达式为 ^$ 模式时 m 标志才有用
            write("m 标志测试:<br/>");
            var str1 = "h1iiiiiiii\r\nh2iiiiiiiii\n\nh3iiiiiiiii";
            write(str1.match(/^h\d/g));
            write("<br/>");
            write(str1.match(/^h\d/m));
            write("<br/>");
            write(str1.match(/^h\d/gm));

        }
        function write(str) {
            document.write(str);
        }
        run();
    </script>
</head>
<body>
</body>
</html>
执行结果:
匹配对象: year:2017 month:6 DAY:24

exec()方法
g 和 gi 参数对比大小写忽略测试:
(/[a-z]+/g):year 4, month 15, 
(/[a-z]+/gi):year 4, month 15, DAY 21, 

参数 g 效果展示:
(/d+/g):2017,6,24
(/\d+/):2017
不带全局属性 g 的只匹配第一个结果

m 标志测试:
h1
h1
h1,h2,h3

以上只是我个人的见解,若您在阅读的过程中发现问题或者你有不同的见解,欢迎留言。
 
【原创内容,转载请注明出处】
It's
欢迎访问本站,欢迎留言、分享、点赞。愿您阅读愉快!
*转载请注明出处,严禁非法转载。
https://www.devsong.org
QQ留言 邮箱留言
头像
引用:
取消回复
提交
涂鸦
涂鸦
热门