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的正则表达式系列文章就到这里结束了,希望对大家有所帮助。

                                  相关文章
                                  |
                                  3月前
                                  |
                                  自然语言处理 JavaScript 前端开发
                                  深入理解JavaScript中的闭包:原理与实战
                                  【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
                                  |
                                  6天前
                                  |
                                  设计模式 数据安全/隐私保护
                                  Next.js 实战 (七):浅谈 Layout 布局的嵌套设计模式
                                  这篇文章介绍了在Next.js框架下,如何处理中后台管理系统中特殊页面(如登录页)不包裹根布局(RootLayout)的问题。作者指出Next.js的设计理念是通过布局的嵌套来创建复杂的页面结构,这虽然保持了代码的整洁和可维护性,但对于特殊页面来说,却造成了不必要的布局包裹。文章提出了一个解决方案,即通过判断页面的skipGlobalLayout属性来决定是否包含RootLayout,从而实现特殊页面不包裹根布局的目标。
                                  50 33
                                  |
                                  13天前
                                  |
                                  前端开发 API 开发者
                                  Next.js 实战 (五):添加路由 Transition 过渡效果和 Loading 动画
                                  这篇文章介绍了Framer Motion,一个为React设计的动画库,提供了声明式API处理动画和页面转换,适合创建响应式用户界面。文章包括首屏加载动画、路由加载Loading、路由进场和退场动画等主题,并提供了使用Framer Motion和next.js实现这些动画的示例代码。最后,文章总结了这些效果,并邀请读者探讨更好的实现方案。
                                  |
                                  11天前
                                  |
                                  JavaScript 前端开发 API
                                  Next.js 实战 (六):如何实现文件本地上传
                                  这篇文章介绍了在Next.js中如何实现文件上传到本地的方法。文章首先提到Next.js官方文档中没有提供文件上传的实例代码,因此开发者需要自行实现,通常有两种思路:使用Node.js原生上传或使用第三方插件如multer。接着,文章选择了使用Node.js原生上传的方式来讲解实现过程,包括如何通过哈希值命名文件、上传到指定目录以及如何分类文件夹。然后,文章展示了具体的实现步骤,包括编写代码来处理文件上传,并给出了代码示例。最后,文章通过一个效果演示说明了如何通过postman模拟上传文件,并展示了上传后的文件夹结构。
                                  |
                                  1月前
                                  Next.js 实战 (二):搭建 Layouts 基础排版布局
                                  本文介绍了作者在Next.js v15.x版本发布后,对一个旧项目的重构过程。文章详细说明了项目开发规范配置、UI组件库选择(最终选择了Ant-Design)、以及使用Ant Design的Layout组件实现中后台布局的方法。文末展示了布局的初步效果,并提供了GitHub仓库链接供读者参考学习。
                                  Next.js 实战 (二):搭建 Layouts 基础排版布局
                                  |
                                  2月前
                                  |
                                  Web App开发 JavaScript 前端开发
                                  2024年5月node.js安装(winmac系统)保姆级教程
                                  本篇博客为2024年5月版Node.js安装教程,适用于Windows和Mac系统。作者是一名熟悉JavaScript与Vue的大一学生,分享了Node.js的基本介绍、下载链接及简单安装步骤。安装完成后,通过终端命令`node -v`验证版本即可确认安装成功。欢迎关注作者,获取更多技术文章。
                                  39 2
                                  2024年5月node.js安装(winmac系统)保姆级教程
                                  |
                                  1月前
                                  |
                                  存储 网络架构
                                  Next.js 实战 (四):i18n 国际化的最优方案实践
                                  这篇文章介绍了Next.js国际化方案,作者对比了网上常见的方案并提出了自己的需求:不破坏应用程序的目录结构和路由。文章推荐使用next-intl库来实现国际化,并提供了详细的安装步骤和代码示例。作者实现了国际化切换时不改变路由,并把当前语言的key存储到浏览器cookie中,使得刷新浏览器后语言不会失效。最后,文章总结了这种国际化方案的优势,并提供Github仓库链接供读者参考。
                                  |
                                  1月前
                                  Next.js 实战 (三):优雅的实现暗黑主题模式
                                  这篇文章介绍了在Next.js中实现暗黑模式的具体步骤。首先,需要安装next-themes库。然后,在/components/ThemeProvider/index.tsx文件中新增ThemeProvider组件,并在/app/layout.tsx文件中注入该组件。如果想要加入过渡动画,可以修改代码实现主题切换时的动画效果。最后,需要在需要的位置引入ThemeModeButton组件,实现暗黑模式的切换。
                                  |
                                  2月前
                                  |
                                  设计模式 前端开发 JavaScript
                                  JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
                                  本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
                                  44 2
                                  |
                                  3月前
                                  |
                                  JavaScript 前端开发 开发者
                                  探索JavaScript原型链:深入理解与实战应用
                                  【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
                                  43 1