TRY REGEX:正则表达式交互式入门教程 翻译&解答

TRY REGEX 是一个交互式的正则表达式学习项目
项目地址:https://github.com/callumacra...
在线地址:http://tryregex.com/
翻译版在线:http://www.rakuhi.com/tryrege...
很适合正则表达式初学者学习、练习
总共28个小课程,从零基础入门到能完成大多数正则表达式书写。

个人做了 翻译&解答,有问题之处欢迎指正


翻译

第一课 正则表达式入门

本交互课程意在介绍正则表达式,更明确的说是JavaScript下的正则表达式。课程当然也会教您用其他语言写正则表达式,但是您应该知道它们是有区别的。
左侧的控制台就是一个JavaScript控制台。请使用 setName('Your name') (Your name替换为您的名字)命令设置您的姓名来开始课程。
还有一些有用的命令:执行 help() 来查看它们

第二课 什么是正则表达式?

正则表达式(也写作 regex 或 regexp)是一个用来描述搜索模式的字符串——类似星号(*)文件名匹配通配符,但更加有效(当然也更加复杂)。
我们将会从一个非常基础的例子开始,来让您掌握 JavaScript 中语法和正则表达式的使用。
bio是一个不知道是否包含您名字的变量。为了看看结果,请输入 bio.match(/{{ firstEscaped }}/);

第三课 包含!

从上个例子中您可以得知一些事情。第一,用于定义正则表达式的语法:使用两个斜杠包含表达式:
/表达式/
如果您将它输入控制台,将会返回正则表达式。
第二,您可以对字符串使用 .match() 方法来测试正则表达式。还有一些其他方法可以调用:您可以直接对正则表达式使用 .exec() 方法来对执行一个字符串。请输入 /{{ firstEscaped }}/.exec(bio)

第四课 简单测试

.exec() 方法和 .match() 方法做的是同样的事情,但它是对表达式调用而不是对字符串——这会很有用。
另一个可用的是 .test() 方法 ——可能是这些方法中最简单的 。类似于 .exec() ,但返回的是布尔值。试一试吧!
提示:左侧控制台可以使用向上键来获取之前输入的表达式。

第五课 字符串替换

我们会用到的最后一个方法是 .replace() ,用一个字符串替换另一个字符串的方法。输入一下内容来将 bio 变量中您的名字隐藏:
bio.replace(/{{ firstEscaped }}/, '[redacted]')

第六课 特殊字符

我们迄今为止用过的表达式都不是特别有趣,也没有包含特殊字符。以下这些字符在正则表达式中应该被转义:

$()*+.?[^|]

为了规避它们,使用反斜杠转义,例如 /what?/
写一个正则表达式来测试 num 变量中是否包含字符串“3.5”。

第七课 点运算符

是不包含的!num 的值是 123456,它不包含字符串“3.5”。
在正则表达式中点运算符有特殊的含义:它将匹配除了换行符以外的所有的单个字符(所以 /a.c/ 将会匹配 "abc", "a c", "a$c" 等等)。未转义点运算符直接使用 /3.5/ 将可能匹配到 num 中字符串,这里点运算符将会匹配 4。
试试吧。

第八课 量词

有一些“量词”可以用来表达某个东西需要被匹配多少次。第一个量词是问号,作用是让前置项(一个字符或字符组)可选(即出现0次或1次)。
表达式 /regexp?/ 将会匹配 "regex" 和 "regexp",问号让 p(只是p)可选。
写一个表达式同时能匹配"frontend" 和 "front-end",答案通过 answer() 函数传参(例子:answer(/表达式/))。

第九课 加号

我们要学习的下一个量词是加号。它的意思是“一个或更多前置项”;/Princes+/ 会匹配 "Princes", "Princess", "Princesssss" 等等。但不会匹配"Prince"。
您要写的下一个表达式将会有点复杂。写一个正则表达式,抽取出 shortStory 变量(可输入 shortStory 查看变量内容)中左右括号间的所有内容(包含括号)。提示:需要用到刚才说过的点运算符。

第十课 星号

星号和加号类似;但是不同于“一个或更多”,星号的含义是“零个或更多的前置项”。/Princes*//Princes+/ 匹配内容的基础上还能匹配 "Prince" 。
重复上一个例子,用星号替换加号。抽取出 shortStory 变量中左右括号间的所有内容,即便括号内没有内容。

第十一课 限制重复次数

有一个量词可以用来限制重复次数。语法是 {min,max} 其中 min 是最小出现次数,max 是最大出现次数。比如 /a{3,5}/ 会且只会匹配 "aaa", "aaaa" 和 "aaaaa"。
写一个表达式匹配 bracketNumbers 中左右圆括号中间长度为5~8之间的字符。

第十二课 限制重复次数进阶

为了进一步明确重复次数范围,您可以用{n}指明确定的一个重复次数,其中 n 是重复次数。比如表达式 a{6} 只会匹配重复的六个 a。
在使用大括号时,您可以不指定最大重复个数,只留下最小重复个数。比如,/a{5,}/ 会匹配5个或更多次重复的字母 a。
answer() 函数给出不使用 ?*+ 字符,但和 /a?b+c*/ 等价的正则表达式。

第十三课 标志——不区分大小写标志

标志用来改变正则表达式的表达形式,位于表达式的后面(例子:/表达式/ig)。每个标志用一个字母表示,JavaScript 支持四种标志——有两种将会在本课程中学到。i 标志让表达式不区分大小写——在没有这个标志时 /a/ 只会匹配“a”,不会匹配“A”;/a/i 则会同时匹配“a”和“A”。
执行 /CAT/i.exec('Category') 来看看 i 标志的作用。

第十四课 标志——全局匹配标志

第二个常用的标志是全局匹配标志,用字母 g 表示。 /a/ 只会匹配字符串中第一个 a, /a/g 则会匹配每一个单个的字母 a。
写一个正则表达式,来用字母 “e” 替换 shortStory 里所有的字母 “a”。
您可以使用字符串的 .replace(expr, replace) 方法来做替换。

第十五课 字符组

字符组允许您指定一组或一个范围的字符去匹配。/[aeiou]/ 匹配任意元音字母,/[a-m]/ 匹配任意字母表前半部分的字母,/[aeiou0-9]/ 匹配任意元音字母或数字。
注意在字符组中,您不需要转义点字符,它将被直接匹配。如果您要使用连字符(-),则需要转义。
我们定义合法的用户名包含5到12个字母(大写字母或小写字母)或连字符。写一段代码,在 username 合法时返回 true

第十六课 否定字符组

否定字符组将会匹配不在字符组内的字符。您可以在字符组前添加一个脱字号(^)来否定它。比如 /[^a-m]/ 将匹配“z” 、“$”,但是不会匹配“c”。
弄清楚 “非 [a-m]” 和 “不在 [a-m] 范围” 的区别很重要,/c[^a]t/ 将匹配 “cut”,但不会匹配 “cat” 和 “ct” ——这个非常重要。
现在合法的用户名可以包含任何非空格字符(但同样长度在 5 到 12 之间)。写出一个正则表达式来检验 username 合法性。

第十七课 类型字符

类型字符可以用作常见字符组的简略表达。有6种类型字符:d 匹配十进制数字(0-9),s 匹配空格, w 匹配单词字符(单词字 —— Unicode字符集、数字、下划线)。
另外三个可用的类型字符是将上面三个改成大写字母,就起到了否定它们的效果;比如 s 匹配所有非空格字符。
写一个正则表达式,能匹配一个后缀一个空格一串数字的单词。用 charTypeTest 测试:不要使用任何文字字符。

第十八课 定位符

如果您想确保字符串以某种确定字(字符集)的开始或结束——比如,您希望包装字符串以大写字母开始——那么你就可以使用锚点。美元符号($)匹配字符串结尾,脱字符(^)匹配字符串开始。/^cat$/ 将只会匹配到 “cat” 而不匹配其他任何字符串(/cat/ 会匹配任何包含 “cat” 的字符串)。
写一个正则表达式来测试 possibleUrl 变量是否以 “http://” 或 “https://” 开始,且从头到尾不包含任何空格。
提示:需要用到问号、否定字符集。您可能会需要两种锚点。

第十九课 捕获组

您可以使用圆括号来创建组,可以将多项组合起来或者保存结果以供之后引用:
/"(.+)"/
上面就是一个捕获组的示例,意思是圆括号内匹配到的字符串将被保存在 .match().exec() 返回的数组中。
回头看看之前我们用表达式 /(.{5,8})/.exec(shorterStory) 抓取两个圆括号之间的数据的例子。尝试用圆括号包住 .{5,8} 重新运行一下。

第二十课 非捕获组

您可以看到现在返回数组有个两项:第一项是全部匹配内容,第二项只包含捕获组匹配数据。
还有一种组类型叫做非捕获组。这种组语法上稍有不同,它不在数组内存储直。如果不需要引用组,您可能倾向使用非捕获组:它会保持返回数组的纯净。上一个例子中,添加 ?: 在组的开始点运算符之前,将表达式变成非捕获组。

第二十一课 量词

和我们zhi'q没有用组几乎一样。
非捕获组的主要用途是给一个组赋予量词。下面的表达式将会匹配 “I ate” 和 Carrot and I ate” 不会匹配其他内容:
/^(?:{{ firstEscaped }} and )?I ate$/
写一个表达式,能够匹配 “ha” 出现两次或更多的字符串 (例如:“haha” 或 “hahahahaha”),用 answer() 函数给出答案。
提示:您的表达式不应该匹配 “hahah”。使用锚点来保证这一点。

第二十二课 管道符号

您可以使用管道符号(|)来指定“或”关系。下面的表达式将匹配 “The dog ate” 和 “The cat ate”:
/The (dog|cat) ate/
您也可以使用非捕获组,但是在这个例子中我们希望获取结果。您可以在一个组内用任意多个管道符号。让上面的表达式在保持原有匹配的基础上也能够匹配 “The rabbit ate” (带匹配串在 rabbit 变量中)。

第二十三课 反向引用

在同一个表达式中,您可以引用之前捕获到的值。只需简单的写成反斜杠后跟着捕获组数字(它在返回字符串里的索引值)。比如,下面的表达式将匹配 “The cat ate with the other cat” 和 “The dog ate with the other dog”,但不会匹配 “The cat ate with the other dog”(当然,这本身就挺奇怪的):
/The (dog|cat) ate with the other 1/
写一个表达式,能够匹配同一行内两个相同的单词(比如:“hello hello world”):和之前的例子一样,用 answer() 函数给出答案。

第二十四课 RegExp对象

除了文字运算符(斜杠),JavaScript 还提供 RegExp 构造器,允许您使用字符串去指定需要的表达式。这个对于将变量放在表达式中非常有用。它的使用方法如下:

// Same as /regexp?/ig
new RegExp('regexp?', 'ig');

用户名同样包含在变量中。 userData 变量包含用户信息:把它打印在控制台中来查看数据格式。使用 username 变量去抽取该用户的关联词。为了能够正确验证,请把答案写在同一行。

第二十五课 高级替换

我们已经知道了两种捕获组使用捕获值得方法:第一种是返回数组,第二种是反向引用。您也可以在 .replace() 方法的第二个参数中获取它:

var text = '*italic text*';
var replace = '<em>$1</em>';
text.replace(/\*([^*]+)\*/, replace);

写一个类似上面的代码,将 boldText 变量替换成 <strong> 元素。

第二十六课 懒惰 vs 贪婪 匹配

JavaScript 默认的匹配模式是 “贪婪”,也就是说匹配尽可能多个:
'"Hi", "Hello"'.match(/".+"/)
上面的表达式将会返回 "Hi", "Hello" ,它匹配了两个双引号间内容。懒惰匹配则和贪婪匹配相反,它会匹配尽可能少的——所以这个例子中,只会匹配 "Hi"
通过在量词后面加上问号来实现懒惰匹配——用上面的例子试试吧。

第二十七课 断言

断言是一个应该被匹配但不会被存储的模式:不是 “匹配a然后匹配b” ,而是 “匹配后面连着b的a,但是不匹配b”。在 JavaScript 中有两种断言类型,肯定先行断言 和 否定先行断言。“先行” 就是说向前查找;JavaScript 不支持 “后行”(向后查找)。
肯定先行断言表示我们想向前查找a的匹配。为了查找a b连接,我们可以使用 /a(?=b)/
使用断言来从 partialSums 中取出 “6+3”。不要使用任何数字符号,用 d

第二十八课 否定断言

断言也可以是否定的,所以我们可以匹配不连接在某项后的字符串。注意和字符组不同的是,它可以匹配到一些不一样的——如果你说 “后面不连着b的a”,a可以在字符串的末尾。
否定断言的语法和肯定断言的语法类似,但用感叹号(!)替换等号:比如,/a(?!b)/ 会匹配后面不是字母 b 的字母 a。
用一个肯定断言接一个否定断言来提取 partialSums 中的 “3+3”。

您完成了课程!

恭喜您,完成了 Try Regex 的课程。您基本上掌握了 JavaScript 中正则表达式的大部分内容,现在您可以写出适用于大多数场景的正则表达式了。
下面这些是延伸阅读内容(不可用链接已替换):


解答

正则表达式的有趣之处就在于,对于同一个问题于有多种不同的写法。下面给出的解答有些只是正确写法中一种,仅供参考。自己思考自己尝试才能真正掌握正则表达式。

第一课 正则表达式入门

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二课 什么是正则表达式?

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第三课 包含!

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第四课 简单测试

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第五课 字符串替换

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第六课 特殊字符

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第七课 点运算符

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第八课 量词

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第九课 加号

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十课 星号

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十一课 限制重复次数

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十二课 限制重复次数进阶

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十三课 标志——不区分大小写标志

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十四课 标志——全局匹配标志

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十五课 字符组

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十六课 否定字符组

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十七课 类型字符

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十八课 定位符

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第十九课 捕获组

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十课 非捕获组

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十一课 量词

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十二课 管道符号

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十三课 反向引用

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十四课 RegExp对象

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十五课 高级替换

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十六课 懒惰 vs 贪婪 匹配

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十七课 断言

TRY REGEX:正则表达式交互式入门教程  翻译&解答

第二十八课 否定断言

TRY REGEX:正则表达式交互式入门教程  翻译&解答

相关推荐