第 1 课:匹配纯文本的模式
本课目标:
- 说出正则表达式是什么,以及它拿什么来做匹配。
- 匹配纯字面量文本,并读懂
test和match的结果。- 区分字面量字符和特殊字符(元字符)。
先修条件:你会在控制台里调用
"text".match(...)这样的方法 | 下一篇 02 >>
你粘贴过的模式,只是一套你没学过的字母表
你复制过“能校验邮箱”的正则,却指不出哪一段在做什么。这不是记性问题:从来没有人把这个模式赖以拼写的字母表交到你手上。正则表达式是一门微型语言,和任何语言一样,它从最乏味的情形讲起:那些只匹配自己的字符。在 \d 和 .+? 不再像乱码之前,你需要先打好地基:模式到底在和什么做匹配,以及“特殊字符”究竟是什么意思。本课只讲这层地基,后面的一切都建在它上面。
讲解
正则表达式(regular expression,简称 regex)是一种用来在字符串里匹配字符组合的模式1。你交给引擎两样东西:一个模式和一个字符串,它告诉你模式是否出现、出现在哪里。在 JavaScript 里,模式写在两条斜杠之间,比如 /cat/,而字符串就是你拿来测试它的那段文本。
最简单的模式是字面量(literal):只匹配自己的字符。模式 /cat/ 匹配确切的序列 “cat”,无论它出现在哪里1。最后这半句比初学者预想的更重要:模式不需要等于整个字符串,只要能在字符串里面被找到就算成功。
你通过方法来运行一个模式。有两个你会一直用到:test 返回 true 或 false,回答“这个模式是否出现在字符串里的任何位置”;match 返回实际匹配到的文本1。正则既可以配合 RegExp 的方法(如 test)使用,也可以配合 String 的方法(如 match)使用1。
不带全局标志时,match 成功后返回一个数组:索引 0 的元素是整个匹配到的文本,另外还带着 index 这样的额外属性,告诉你它在哪里被找到2。眼下,把索引 0 的元素读成“模式匹配到的那段子串”就够了。
到目前为止,每个字符都是字面量。但有些字符是特殊字符:它们是指令,不是字母。当你需要的不止是直接匹配,比如“某样东西出现一次或多次”或“任意一个数字”,就要在模式里使用特殊字符1。.、*、+、?、^、$、[、]、(、) 和 \ 这些字符不匹配它们自己,每一个都是一段语法。这些特殊字符叫作元字符(metacharacter),后面的每一课其实都是在一次讲清其中一小群。眼下,你只需要在脑子里记住这个划分:字母和数字是字面量,那一小撮标点符号是指令。
完整示例(跟着做)
假设你想知道一行日志是否提到了错误。打开浏览器 DevTools 控制台(或 Node REPL),试一下:
一步步看:/ERROR/ 是五个字面量字符,没有一个是特殊字符,所以引擎寻找确切的连续文本 “ERROR”,没有找到,返回 false。/WARN/ 在索引 11 处被找到,所以 test 返回 true,match 交回匹配到的文本和它的位置。你没有做任何花哨的事:你搜索了字面量文本,然后读了结果。
你来试试(填空示例)
你想检查一个文件名是否包含单词 “draft”。填上缺失的那一块,让这个检查成为一次字面量搜索:
答案:空格处填字面量 draft,得到 /draft/.test(name)。d-r-a-f-t 这几个字符都是字面量,引擎搜索这段确切的连续文本,在 “report-draft-2.md” 里找到了它,返回 true。注意你从头到尾都不需要让模式等于整个文件名:字面量模式只要在字符串任何位置被找到就匹配成功。
小结 + 下节课预告
正则是拿来和字符串做匹配的模式。字面量字符匹配自己,字面量模式只要在字符串任何位置被找到就算成功,不需要等于整个字符串。test 返回布尔值;match 在索引 0 处返回匹配到的文本。还有一些字符是元字符:它们是指令,不是字母。下一课我们会见到第一族真正的元字符:字符类。它让模式里的一个位置匹配一整组字符,而不是单个固定的字母,我们也会最终钉清那个 . 到底做什么。
Footnotes
-
MDN: Regular expressions (JavaScript Guide) — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions ↩ ↩2 ↩3 ↩4 ↩5
-
MDN: String.prototype.match() — https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match ↩
Exercises
仍然在控制台里,运行 "a.b.c".match(/./)。你预期会匹配到字面量的点,但看看索引 0 的元素实际是什么。然后用一句话解释为什么结果是这样。
第 2 级(进阶)My note
Jot down thoughts, sticking points, things you didn't get. Written to this course's appendix only — the lesson file is never touched.