JavaScript正则表达式的模式匹配教程,并且附带充足的实战代码(四 | 完结)

简介: 我们继续来学习正则表达式吧,没有看过之前文章的小伙伴建议点击上方链接,从第一篇开始看,本系列文章适合从未接触过或不太了解正则表达式的人

修饰符


正则表达式的修饰符是用以说明高级匹配模式的规则,并且修饰符是放在// 双斜杠外面的,例如这样 /java/g,g就是修饰符


接下来给出一张表,列出了修饰符的种类和含义


字符
含义
i
执行不区分大小写的匹配
g
执行全局匹配,即找到所有匹配的项并返回,而不是找到第一个之后就停止
m
多行匹配模式


我们来逐个讲解它们各自的用途:


  • 字符 i


我们之前会用这样的匹配模式去匹配 /[Jj]ava[Ss]cript/,这是因为我们不知道字符串中写的是 javascript 还是 JavaScript。其实我们可以直接用一个修饰符 i 来避免大小写的干扰,就想这样 /javascript/i


    let pattern = /javascript/ilet str = "JavaScript"
    str.match(pattern)        // 返回 ['JavaScript']  匹配成功


    我们可以看到,匹配时忽略了大小写的影响,仍然匹配成功了


    • 字符 g


    我们之前匹配字符串时,都是匹配到第一个就结束匹配返回内容,例如


      let pattern = /java/let str = "I love javascript and java"
      str.match(pattern)      //返回 ["java"]  匹配到javascript的java就返回了


      我们可以看到 str 字符串中,有两个java,但只匹配到javascript就返回了,如果我们要匹配到字符串中所有符合匹配模式的字符串,我们就可以用修饰符g,就像这样 /java/g


        let pattern = /java/glet str = "I love javascript and java"
        str.match(pattern)    //返回 ["java", "java"] 匹配到了所有的java


        • 字符 m


        如果一个字符串中包含换行符,则该字符串就有多行。这时我们可以使用修饰符 m 进行多行模式的匹配。


          let pattern = /java$/mlet str = "java\nis fun"
          str.match(pattern)            //返回 ['java'] 匹配成功


          在这个例子中,str内有一个换行符,这样的话,第一行就是 java ,第二行就是 is fun 。我们的匹配模式是查找每一行,只要这一行的结尾是java,就返回匹配到的内容。


          其实在这个例子中,我们看到,使用了修饰符 m 以后,锚字符 ^ 和 $ 不再是以一整个字符串的开头或结尾为匹配点了,而是以每一行的开头或结尾为匹配点。


          用于模式匹配字符串的方法


          我们在前面的很多例子中用到了search()方法 、match()方法,他们都是匹配字符串的方法,其实还有很多种匹配的方法,他们的用法和作用各不相同,我们来了解一下

          用于模式匹配字符串的方法有以下几种:


          1. search( )


          1. replace( )


          1. match( )


          1. split()


          接下来我们来详细讲解一下


          • search()


          该方法需要传入一个正则表达式作为参数,并返回第一个与之匹配的字符串的起始位置,若没匹配到,则返回-1


            "javascript".search(/script/)      //返回 4
            "javascript".search(/sccc/)        //返回-1


            • replace()


            该方法是用于字符串的检索与替换。需要传入两个参数,第一个参数为正则表达式;第二个参数为需要进行替换的字符串。匹配成功则会用第二个参数去替换匹配到的字符串,并返回替换后的整体字符串;若没匹配成功,则返回原来的整体字符串。


              "javascript".replace(/java/, 'python')  //返回 pythonscript
              "javascript".replace(/abc/, 'python')   //返回 javascript


              若使用了修饰符g,则会将所有匹配到的字符串都进行一个替换。


                "javascript and java".replace(/java/, 'python')  //返回 pythonscript and java"javascript".replace(/java/g, 'python')   //返回 pythonscript and python


                • match()


                该方法需要传入一个正则表达式作为参数,返回一个由匹配结果组成的数组,如果正则表达式使用了修饰符g,则将所有匹配到的结果都放到数组中并返回。


                  "javascript and java".match(/java/)   //返回 ['java']
                  "javascript and java".match(/java/g)   //返回 ['java', 'java']


                  补充:当match()传入一个非全局的正则表达式时,实际上返回的数组里有两个属性:index和input,他们分别表示匹配到的字符串的起始位置和检索的整个字符串。


                    let ret = "I love javascript and java".match(/java/)ret.index        //返回  7ret.input        //返回 I love javascript and java


                    • split()


                    该方法是用于将字符串分割,并将分割开的部分作为数组中的元素,最终返回一个数组。该方法需要传入一个正则表达式作为参数,去确定需要根据什么去分割这串字符串,若匹配成功,最终返回一个数组,数组中的元素就是每个被分割的字符串;若匹配失败,也会返回一个数组,数组中只有一个元素,那就是这个字符串整体。


                      '1,2,3,4,5,6'.split(/,/)   //返回 ['1', '2', '3', '4', '5', '6']
                      '1,2,3,4,5,6'.split(/\+/)  //返回 ['1,2,3,4,5,6']


                      RegExp对象的方法


                      RegExp对象定义了两个用于匹配的方法——exec()test(),这两个方法与我们之前讲到的用于模式匹配字符串的方法不同的是,前者是定义在RegExp对象上的方法,并且传入的参数是字符串;而后者是调用字符串的方法,传入的参数是RegExp对象。


                      • exec()


                      该方法就跟前面说到的不传入修饰符g的matach()方法一样,它对字符串执行一个正则表达式,如果匹配失败,返回null;如果匹配成功,则返回一个数组,数组的第一个元素是正则表达式匹配到的字符串,剩下的元素则是子表达式匹配到的字符串,同时该数组也包含indexinput两个属性。


                      来看一个例子,体会一下exec()方法的作用


                        let pattern = new RegExp("java", "g")let ret = pattern.exec("I love javascript and java")  //返回["java"]
                        ret.index     //返回 7ret.input     //返回 I love javascript and java


                        exec()match() 方法不同的是,不管正则表达式是否使用修饰符g,exec()都只会将第一个匹配到的字符串以及子表达式匹配到的字符串放到数组里返回;而match()方法在没有使用修饰符g时,跟exec()一样,如果使用了修饰符g,则将所有匹配到的字符串都放在数组里一起返回,并且不会返回圆括号里匹配到的字符串,同时,该数组里不包含indexinput两个属性。


                        那么这里引发一个疑问,既然不管是否使用修饰符g,exec()方法都只会返回第一个匹配到的字符串,那这个修饰符g有什么用呢?其实我们在前面有说到,RegExp对象内有一个属性叫做 lastIndex,该属性默认为0。当我们调用exec()方法,并且使用了修饰符g进行匹配时,若匹配成功,lastIndex将变为下一次检索开始位置的索引值;若匹配失败,lastIndex则重置为0


                          let pattern = new RegExp("java", "g")console.log(pattern.lastIndex)        //查看lastIndex默认为0let str = "I love javascript and java"
                          pattern.exec(str)               //进行第一次检索匹配,返回["java"]console.log(pattern.lastIndex)  //此时lastIndex为 4
                          pattern.exec(str)               //进行第二次检索匹配,返回["java"]console.log(pattern.lastIndex)  //此时lastIndex为 19
                          pattern.exec(str)               //进行第三次检索匹配,返回nullconsole.log(pattern.lastIndex)  //此时lastIndex为  0


                          从上面这个例子我们能看看到,lastIndex默认为0,表示从字符串的开头开始检索,当我们进行第一次检索时,匹配到了javascript中的java,返回了该字符串,这时lastIndex变为第一次匹配到的字符串的起始位置索引 4;我们进行第二次索引,是从索引 5 开始匹配的,往后检索到字符串末尾的java,并返回该字符串,同时lastIndex变为第二次匹配到的字符串起始位置索引 19;我们进行第三次索引,是从索引 20 开始匹配的,往后匹配,已经无法匹配到对应的字符串了,所以返回一个null,并将lastIndex重置为0,表示下一次检索又从字符串的开头开始检索。


                          • test()


                          该方法与exec()类似,该方法也是传入一个字符串作为参数,对该字符串进行检索,如果匹配到了相应的字符串,则返回true;如果没匹配到,则返回false。


                            let pattern = new RegExp("java", "g")let ret = pattern.test("I love javascript and java")  //返回 true

                            test() 与 exec() 相同的是,如果匹配时使用了修饰符g,test()也会根据对象内部属性 lastIndex 进行检索匹配,这里就不多做说明了。


                            正则表达式实战应用


                            (1)判断电话号码格式


                            应用场景:判断用户输入的电话号码格式是否正确


                            电话号码格式:1开头,后面跟10位数字


                              let str = "12356456132"  //str为用户输入的电话号码let re = /^1\d{10}$/     if(re.test(str) !== true) {  console.log('电话号码格式不正确')}else {  console.log('电话号码格式正确')}


                              (2)判断邮箱格式


                              应用场景:判断用户输入的邮箱格式是否正确


                              邮箱格式:第一部分@第二部分,第一部分由字母、数字 和 短横线 - 组成,第二部分由(字母、数字、短横线 - ).cn.com…… 组成


                                let str = "561325647@qq.com"    //用户输入的邮箱let re = /^[\w-\.]+@(\w-?)+(\.\w{2,})+$/if(re.test(str) !== true) {  console.log('邮箱格式不正确')}else {  console.log('邮箱格式正确')}

                                (3)判断昵称格式


                                应用场景:判断用户输入的昵称是否符合规定格式


                                昵称格式:昵称由字母、数字、下划线组成,必须由字母开头,长度为4-16位


                                  let str = "Lpyexplore233"     //用户输入的昵称let re = /^[a-zA-Z][\w_]{3,15}$/if(re.test(str) !== true) {  console.log('昵称格式不正确')}else {  console.log('昵称格式正确')}


                                  结束语


                                  JavaScript的正则表达式系列文章就到这里结束了,希望对大家有所帮助。

                                  相关文章
                                  |
                                  4月前
                                  |
                                  人工智能 自然语言处理 JavaScript
                                  通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
                                  通义灵码基于自然语言需求,快速生成完整Vue组件。例如,用Vue 2和JavaScript实现贪吃蛇游戏:包含键盘控制、得分系统、游戏结束判定与Canvas动态渲染。AI生成的代码符合规范,支持响应式数据与事件监听,还能进阶优化(如增加启停按钮、速度随分数提升)。传统需1小时的工作量,使用通义灵码仅10分钟完成,大幅提升开发效率。操作简单:安装插件、输入需求、运行项目即可实现功能。
                                  227 4
                                   通义灵码2.5实战评测:Vue.js贪吃蛇游戏一键生成
                                  |
                                  2月前
                                  |
                                  JavaScript 前端开发 算法
                                  流量分发代码实战|学会用JS控制用户访问路径
                                  流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
                                  73 1
                                  |
                                  3月前
                                  |
                                  机器学习/深度学习 JavaScript 前端开发
                                  JS进阶教程:递归函数原理与篇例解析
                                  通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
                                  129 19
                                  |
                                  6月前
                                  |
                                  资源调度 JavaScript 前端开发
                                  前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
                                  本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
                                  5159 24
                                  |
                                  6月前
                                  |
                                  监控 JavaScript 前端开发
                                  MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
                                  MutationObserver 是一个非常强大的 API,提供了一种高效、灵活的方式来监听和响应 DOM 变化。它解决了传统 DOM 事件监听器的诸多局限性,通过异步、批量的方式处理 DOM 变化,大大提高了性能和效率。在实际开发中,合理使用 MutationObserver 可以帮助我们更好地控制 DOM 操作,提高代码的健壮性和可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
                                  MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
                                  |
                                  7月前
                                  |
                                  人工智能 算法 Ubuntu
                                  动态规划篇】正则表达式与通配符:开启代码匹配的赛博奇幻之旅
                                  动态规划篇】正则表达式与通配符:开启代码匹配的赛博奇幻之旅
                                  |
                                  9月前
                                  Next.js 实战 (二):搭建 Layouts 基础排版布局
                                  本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
                                  286 1
                                  Next.js 实战 (二):搭建 Layouts 基础排版布局
                                  |
                                  JavaScript 前端开发 API
                                  Next.js 实战 (六):如何实现文件本地上传
                                  这篇文章介绍了在Next.js中如何实现文件上传到本地的方法。文章首先提到Next.js官方文档中没有提供文件上传的实例代码,因此开发者需要自行实现,通常有两种思路:使用Node.js原生上传或使用第三方插件如multer。接着,文章选择了使用Node.js原生上传的方式来讲解实现过程,包括如何通过哈希值命名文件、上传到指定目录以及如何分类文件夹。然后,文章展示了具体的实现步骤,包括编写代码来处理文件上传,并给出了代码示例。最后,文章通过一个效果演示说明了如何通过postman模拟上传文件,并展示了上传后的文件夹结构。
                                  208 0
                                  Next.js 实战 (六):如何实现文件本地上传
                                  |
                                  前端开发 API 开发者
                                  Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
                                  这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
                                  269 0
                                  Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
                                  |
                                  存储 网络架构
                                  Next.js 实战 (四):i18n 国际化的最优方案实践
                                  这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
                                  513 0
                                  Next.js 实战 (四):i18n 国际化的最优方案实践