文章 | 吃透 <正则表达式>(理论+多图示例)

1,633 阅读3分钟

翻译,原文来自:Regex tutorial — A quick cheatsheet by examples[1]

掘金编辑器格式化效果不太好,可以去我们的公众号浏览:

mp.weixin.qq.com/s?__biz=MzI…


通过正则表达式在从文本中提取特定模式的内容时非常有用。

它应用很广泛,包括:验证、解析/替换字符串、数据格式转换以及网页爬取。

一旦你学会了它的语法,你几乎可以在所有编程语言(JavaScript、Java、VB、C#、C/C++、Python、Perl、Ruby、Delphi、R、Tcl 等等)中使用它。

让我们先看看一些示例和讲解吧。



基础

标记点(Anchors):^ 和 $

• ^The — 匹配任意以 The 开头的字符串


• end$ — 匹配以 end 结尾的字符串
• ^The end$ — 字符串完整匹配 (也就是 The end)
• roar — 包含 roar 的任何字符串


量词:* + ? 和 {},即表示数量的

• abc* — 匹配 ab 并且后面跟着 0 个或多个 c 的字符串


• abc+ — 匹配 ab 并且后面跟着 1 个或多个 c 的字符串(至少一个 c)
• abc? — 匹配 ab 并且后面跟着 0 个或 1 个 c 的字符串
• abc{2} — 匹配 ab 并且后面跟着 2 个 c 的字符串
• abc{2,} — 匹配 ab 并且后面跟着 2 个或更多个 c 的字符串(至少 2 个)
• abc{2,5} — 匹配 ab 并且后面跟着 2 到 5 个 c 的字符串
• a(bc)* — 匹配 a 并且后面跟着 0 个或多个 bc 的字符串
• a(bc){2,5} — 匹配 a 并且后面跟着 2 个到 5 个 bc 的字符串


或操作符:| 或 []

a(b|c) — 匹配 a 并且后面跟着 b 或 c 的字符串(也就是 ab 或 ac)


• a[bc] — 同上


字符类:\d \w \s 和 .

• \d — 匹配一个数字(等同于 [0-9]


• \w — 匹配文字字符(word character)(注:这里指的英文:数字、字母和下划线。等同于 [a-zA-Z0-9_])


• \s — 匹配空格符(包括制表符(tab) 和换行,等同于 [\r\n\t\f\v ]


— 匹配任意字符




在使用 . 时要注意,有时使用字符类(\d, \s. \w)和反字符会更快更精准。

\d, \s\w 的反义类是 \D, \W\S(大写)。

例如:\D 得到与 \d 相反的结果。

• \D — 匹配一个非数字字符 


想要匹配 ^.[$()|*+?{\ 等这些字符,要使用 \ 进行转义。

• $\d — 匹配一个 $ 和一个数字


提示:通过正则表达式可以匹配那些不可打印的字符,例如:制表符(tab)用 \t、换行用 \n、回车用 \r

标记(Flags)

正则通常以/abc/这种形式呈现,搜索模式以两个/进行分隔。并在结尾加上以下标记符:

• g (global) 返回所有匹配的
• m(multi-line)多行匹配,再同时使用 ^$ 时会在多行匹配,而不是按完整的字符串匹配。
• i(insensitive)不区分大小写,例如:/aBc/i 能匹配 AbC

中级

捕获分组(Grouping and capturing): ()

• a(bc) — 用小括号创建值是 bc 的捕获组 


• a(?:bc)* — 使用 ?: 来禁用捕获组



• a(?<foo>bc) — 使用 ?<foo> 给组命名



在数据提取中使用这种操作符非常实用,多个捕获分组会以数组形式呈现,所以可以通过索引获取这些值。

如果我们使用组命名 (?<foo>...),我们就可以像使用字典(对象)一样,通过键名来取值。


中括号表达式:[]

• [abc] — 匹配 或是 a、或是 b、或是 c 的字符串(等同于:a|b|c


• [a-c] — 同上•[a-fA-F0-9] — 匹配一个十六进制数字,不区分大小写 


• [0-9]% — 匹配 % 前有一个 0 到 9 任意数字的字符串•[^a-zA-Z] — 匹配不包括 a 到 z,及 A 到 Z 的字符串,这里的 ^ 是一个取反表达式 




贪婪和懒惰(非贪婪)匹配

* + {}这几个量词就是贪婪操作符,什么意思?就是他们会匹配尽可能多的内容。

例如:<.+> 会从 This is a <div>simple div</div> test 中匹配出 <div>simple div</div>,如果我们只想要 div 标签,只需加上 ? 使其变成懒惰的。


• <.+?>懒惰匹配 < 和 > 里任意字符


提示:最好避免使用 .,而选择严格的匹配方式。

• <[^<>]+> — 匹配在 < 和 > 里除了 < 和 > 外的任意字符



高级

边界:\b 和 \B(也就是单词边界)

• \babc\b — 词 abc


\b 是和 $^ 类似的一个标记点。它的一侧是单词(\w),而另一侧不是单词(字符串的起始位置或空格)。

它的反义就是 \B

• \Babc\B — 匹配有单词包围的 abc



后向引用(Back-references):\1

• ([abc])\1 — 使用 \1 匹配和第一个捕获组一样的文字


• ([abc])([de])\2\1 — 使用 \2 (\3, \4 等) 来匹配和第 2 个(第 3 个、第 4 个等)捕获组一样的文字 


• (?<foo>[abc])\k<foo> — 给捕获组命名为 foo 再通过 \k<foo> 引用他,同第一个例子结果一样



向前、向后:(?=) 和 (?<=)

• d(?=r) — 匹配 r 前面的 d,不包括 r 


• (?<=r)d — 匹配 r 后面跟着的 d,不包括 r


或使用反义操作

• d(?!r) — 匹配 r 后面跟着的 d,不包括 r 


• (?<!r)d — 匹配 r 前面的 d,不包括 r



总结

如你所见,正则表达式的应用字段可以是多个的,估计你在开发中或多或少也用过一些,下面是几个常见的场景:

•数据验证(例如,检查时间格式是否正确)•数据爬取(如网页爬虫,对内容的查找)•数据整理(Data Wrangling),将原始数据转换另一种格式•字符串解析(例如,URL GET参数)•字符串替换•语法高亮显示、文件重命名等


极客阅读 | 汇聚了国内外最优质的技术博客、产品动态、公众号文章。

官网geeker-read.com