跳到主要内容

归纳

锚点:

^:从开头开始匹配。^ 用来检查匹配的字符串是否在所匹配字符串的开头。在 abc 中使用表达式 ^a 会得到结果 a。但如果使用 ^b 将匹配不到任何结果。因为在字符串 abc 中并不是以 b 开头。

$:从结尾开始匹配。$ 号用来匹配字符是否是最后一个。

标志:

i:忽略大小写

g: 匹配全局,不然默认就是只匹配第一个符合要求的字符

m: 匹配多行

分组:

(xyz):一个字符集,匹配与 xyz 完全相等的字符串。

字符:

[]:匹配方括号内的任意字符。

[^]:方括号内的尖箭头表示否定,匹配除了方括号之内的任意字符。

[a-z]: 表示范围,包括本身

.:(英文点)匹配任意字符。

\w:匹配所有的字母和数字,还有下换线。相当于[a-zA-Z0-9_]

\W:匹配非字母和数字,相当于[^\w]

\d:匹配数字: [0-9]

\D:匹配非数字: [^\d]

\s: 匹配所有空格字符

\S: 匹配所有非空格字符

零宽断言:

量词与分支:

+:加号表示匹配 1 个及以上,也就是至少 1 个。

*:星号表示匹配 0 个及以上个符号,也就是没有或者有很多都可以。

{n,m}:大括号内的两个数字表示匹配一定数量的大括号之前的字符或者字符集。这个一定数量就是在 n 到 m 之间。如果 m 没写就是没有最大值。

?:问号匹配 0 个或者 1 个。也可以用来把贪婪匹配变为懒惰匹配。

|:或运算符,匹配符号前面或者后面的字符。

\:转义字符,针对一些特殊字符如(){}[]等字符匹配这些字符本身时,需要转义字符。

注意:如".ar" => The car parked in the garage. ,一个点只匹配一位,不是无限向前匹配很多位。如果需要很多次数匹配,需要*?+等符号

https://regexlearn.com/zh-cn/playground

注意:正则表达式默认采用贪婪匹配模式,在该模式下意味着会匹配尽可能长的子串。我们可以使用 ? 将贪婪匹配模式转化为惰性匹配模式。


笔记

下面来自《正则表达式必知必会》这本书,本文导出了部分我的划线读书笔记。

◆ 1.2 如何使用正则表达式

正则表达式的两种基本用途:搜索和替换。给定一个正则表达式,它要么匹配一些文本(进行一次搜索),要么匹配并替换一些文本(进行一次替换)。

◆ 1.3 什么是正则表达式

正则表达式是一些用来匹配和处理文本的字符串。

◆ 2.1 匹配纯文本

正则表达式可以包含纯文本(甚至可以只包含纯文本)

绝大多数正则表达式引擎的默认行为是只返回第 1 个匹配结果

比如说,在 JavaScript 里,可选的 g(意思是“global”,全局)标志将返回一个包含着所有匹配的结果数组。

正则表达式是区分字母大小写的

JavaScript 用户可以用 i 标志来强制执行一次不区分字母大小写的搜索。

◆ 2.2 匹配任意字符

·字符(英文句号)可以匹配任何一个单个的字符。

正则表达式可以用来匹配包含着字符串内容的模式。匹配的并不总是整个字符串,而是与某个模式相匹配的字符——即使它们只是整个字符串的一部分。

.字符可以匹配任何单个的字符、字母、数字甚至是.字符本身。

同一个正则表达式里允许使用多个.字符,它们既可以连续出现(一个接着一个——..将匹配任意两个字符),也可以间隔着出现在模式的不同位置。

◆ 2.3 匹配特殊字符

你必须在.的前面加上一个\(反斜杠)字符来对它进行转义。\是一个元字符(metacharacter,表示“这个字符有特殊含义,而不是字符本身含义”)。

在正则表达式里,\字符永远出现在一个有着特殊含义的字符序列的开头,这个序列可以由一个或多个字符构成。

在绝大多数的正则表达式实现里,.只能匹配除换行符以外的任何单个字符

◆ 3.1 匹配多个字符中的某一个

在正则表达式里,我们可以使用元字符[和]来定义一个字符集合。在使用[和]定义的字符集合里,这两个元字符之间的所有字符都是该集合的组成部分,字符集合的匹配结果是能够与该集合里的任意一个成员相匹配的文本。

[和]不匹配任何字符,它们只负责定义一个字符集合。

字符集合在不需要区分字母大小写(或者是只须匹配某个特定部分)的搜索操作里比较常见

◆ 3.2 利用字符集合区间

为了简化字符区间的定义,正则表达式提供了一个特殊的元字符——字符区间可以用-(连字符)来定义。

字符区间并不仅限于数字,以下这些都是合法的字符区间:

❑ A-Z,匹配从 A 到 Z 的所有大写字母。

❑ a-z,匹配从 a 到 z 的所有小写字母。

❑ A-F,匹配从 A 到 F 的所有大写字母。

❑ A-z,匹配从 ASCII 字符 A 到 ASCII 字符 z 的所有字母。这个模式一般不常用,因为它还包含着[和^等在 ASCII 字符表里排列在 Z 和 a 之间的字符。

在定义一个字符区间的时候,一定要避免让这个区间的尾字符小于它的首字符(例如[3-1])。

-(连字符)是一个特殊的元字符,作为元字符它只能用在[和]之间。在字符集合以外的地方,-只是一个普通字符,只能与-本身相匹配。因此,在正则表达式里,-字符不需要被转义。

在同一个字符集合里可以给出多个字符区间。

◆ 3.3 取非匹配

元字符^来表明你想对一个字符集合进行取非匹配

^的效果将作用于给定字符集合里的所有字符或字符区间,而不是仅限于紧跟在^字符后面的那一个字符或字符区间。

◆ 3.4 小结

字符集合可以用元字符^来求非;

◆ 4.1 对特殊字符进行转义

元字符是一些在正则表达式里有着特殊含义的字符。

因为元字符在正则表达式里有着特殊的含义,所以这些字符就无法用来代表它们本身。

每个元字符都可以通过给它加上有个反斜杠前缀的办法来转义,如此得到的转义序列将匹配那个字符本身而不是它特殊的元字符含义。

任何一个元字符都可以通过给它加上一个反斜杠字符(\)作为前缀的办法来转义,能够被转义的元字符并不仅局限于我们这里提到的那几个

配对的元字符(比如[或])不用作元字符时必须被转义,否则正则表达式分析器很可能会抛出一个错误。

\字符也是一个元字符——它的特殊含义是对其他元字符进行转义。

在一个完整的正则表达式里,字符\的后面永远跟着另一个字符

◆ 4.2 匹配空白字符

表 4-1 空白元字符

\r\n 匹配一个“回车+换行”组合,

r\n 是 Windows 所使用的文本行结束标签。Unix 和 Linux 系统只使用一个换行符来结束一个文本行;换句话说,在 Unix/Linux 系统上匹配空白行只使用\n\n 即可,不需要加上\r。同时适用于 Windows 和 Unix/Linux 系统的正则表达式应该包含一个可选的\r 和一个必须被匹配的\n

.和[是元字符,但前提是你没有对它们进行转义。f 和 n 也是元字符,但前提是你对它们进行了转义。如果你没有对 f 和 n 进行转义,它们将被解释为普通字符,只能匹配它们本身

◆ 4.3 匹配特定的字符类别

表 4-2 数字元字符

正则表达式的语法是区分字母大小写的。\d 匹配数字,\D 与\d 的含义刚好相反。

字母和数字——A 到 Z(不分大小写)、数字 0 到 9、再加上下划线字符(_)——是另一种比较常用的字符集合

表 4-3 字母数字元字符

表 4-4 空白字符元字符

用来匹配退格字符的[\b]元字符是一个特例:它不在类元字符\s 的覆盖范围内,当然也就没有被排除在类元字符\S 的覆盖范围外。

◆ 4.4 使用 POSIX 字符类

POSIX 字符类是许多(但不是所有)正则表达式实现都支持的一种简写形式。

JavaScript 不支持在正则表达式里使用 POSIX 字符类。

表 4-5 POSIX 字符类

◆ 5.1 有多少个匹配

+匹配一个或多个字符(至少一个;不匹配零个字符的情况)。

在给一个字符集合加上+后缀的时候,必须把+放在这个字符集合的外面。

+是一个元字符。如果需要匹配+本身,就必须使用它的转义序列+

+还可以用来匹配一个或多个字符集合。

\w 只能匹配字母和数字字符,不能匹配出现在字符串中间的.字符

一般来说,当在字符集合里使用的时候,像.和+这样的元字符将被解释为普通字符,不需要被转义——但转义了也没有坏处。[\w.]的使用效果与[\w\ .]是一样的。

*的用法与+完全一样——只要把它放在一个字符(或一个字符集合)的后面,就可以匹配该字符(或字符集合)连续出现零次或多次的情况。

与+的区别是:+匹配一个或多个字符(或字符集合),最少要匹配一次;*匹配零个或任意多个字符(或字符集合),可以没有匹配。

是一个元字符。如果需要匹配*本身,就必须使用它的转义序列*

?只能匹配一个字符(或字符集合)的零次或一次出现,最多不超过一次

?是一个元字符。如果需要匹配?本身,就必须使用它的转义序列\?。

◆ 5.2 匹配的重复次数

重复次数要用{和}字符来给出——把数值写在它们之间。

{和}是元字符。如果需要匹配{和}本身,就应该用\对它们进行转义

{}语法还可以用来为重复匹配次数设定一个区间——也就是为重复匹配次数设定一个最小值和一个最大值。这种区间必须以{2, 4}这样的形式给出——{2, 4}的含义是最少重复 2 次、最多重复 4 次

为避免不必要的麻烦,在需要匹配/字符本身的时候,你最好总是使用它的转义序列。

{3, }表示至少重复 3 次,与之等价的说法是“必须重复 3 次或更多次”。

◆ 5.3 防止过度匹配

?只能匹配零个或一个字符,{n}和{m, n}也有一个重复次数的上限;换句话说,这几种语法所定义的“重复次数”都是有限的。

因为*和+都是所谓的“贪婪型”元字符,它们在进行匹配时的行为模式是多多益善而不是适可而止的。它们会尽可能地从一段文本的开头一直匹配到这段文本的末尾,而不是从这段文本的开头匹配到碰到第一个匹配时为止。

懒惰”在这里的含义是匹配尽可能少的字符——与“贪婪型”元字符的行为模式刚好相反)

表 5-1 常用的贪婪型元字符和它们的懒惰型版本

◆ 5.4 小结

+(匹配字符或字符集合的一次或多次重复出现)、*(匹配字符或字符集合的零次或多次重复出现)、?(匹配字符或字符集合的零次或一次出现)等几个元字符的用法。要想获得更精确的控制,你可以用{ }语法来精确地设定一个重复次数或是重复次数的最小值和最大值。元字符分“贪婪型”和“懒惰型”两种;在需要防止过度匹配的场合下,请使用“懒惰型”元字符来构造你的正则表达式。

◆ 6.1 边界

使用边界限定符,也就是在正则表达式里用一些特殊的元字符来表明我们想让匹配操作在什么位置(或边界)发生。

◆ 6.2 单词边界

\b 用来匹配一个单词的开始或结尾

\b 匹配的是一个这样的位置,这个位置位于一个能够用来构成单词的字符(字母、数字和下划线,也就是与\w 相匹配的字符)和一个不能用来构成单词的字符(也就是与\W 相匹配的字符)之间。

b 匹配且只匹配一个位置,不匹配任何字符。用\bcat\b 匹配到的字符串的长度是 3 个字符(c、a、t),不是 5 个字符

如果你想表明不匹配一个单词边界,请使用\B

\B-\B 将匹配一个前后都不是单词边界的连字符。

◆ 6.3 字符串边界

用来定义字符串边界的元字符有两个:一个是用来定义字符串开头的^,另一个是用来定义字符串结尾的$。

^是几个有着多种用途的元字符之一。只有当它出现在一个字符集合里(被放在[和]之间)并紧跟在左方括号[的后面时,它才能发挥“求非”作用。如果是在一个字符集合的外面并位于一个模式的开头,^将匹配字符串的开头。

^匹配一个字符串的开头位置,所以^\s将匹配一个字符串的开头位置和随后的零个或多个空白字符(这解决了<? xml>标签前允许有空格、制表符、换行符等空白字符的问题)。作为一个整体,模式^\s<\? xml.*\? >不仅能正确地匹配一个位置正确的<? xml>标签,还能对合法的空白字符做出妥善处理。

用来启用分行匹配模式(multiline mode)的(? m)记号就是一个能够改变其他元字符行为的元字符序列。

在使用时,(? m)必须出现在整个模式的最前面,

加上(? m)前缀之后,(? m)^\s//.$将把换行符视为一个字符串分隔符,这样就可以把每一行注释都匹配出来了。

有许多正则表达式实现不支持(? m)。

◆ 6.4 小结

\b 用来指定一个单词边界(\B 刚好相反)。^和$用来指定字符串边界(字符串的开头和字符串的结束)。如果与(? m)配合使用,^和$还将匹配在一个换行符处开头或结束的字符串(此时,换行符将被视为一个字符串分隔符)。

◆ 7.1 什么是子表达式

{2, }只作用于紧挨着它的前一个字符——那是一个分号。如此一来,这个模式只能匹配像  ; ; ;;这样的文本,但无法匹配   

◆ 7.2 子表达式

把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素来使用。子表达式必须用(和)括起来。

这个模式里的|字符是正则表达式语言里的或操作符,

因为|操作符是把位于它左边和右边的两个部分都作为一个整体来看待的,它会把模式 19|20\d{2}解释为 19 或 20\d{2}(也就是把\d{2}解释为以 20 开头的那个表达式的一部分)。

◆ 8.2 回溯引用匹配

回溯引用允许正则表达式模式引用前面的匹配结果

回溯引用指的是模式的后半部分引用在前半部分中定义的子表达式(如上例所示)。

不同的正则表达式在实现回溯引用的语法方面往往有着巨大的差异。

回溯引用只能用来引用模式里的子表达式(用(和)括起来的正则表达式片段)。

回溯引用匹配通常从 1 开始计数(\1、\2,等等)。在许多实现里,第 0 个匹配(\0)可以用来代表整个正则表达式

◆ 8.3 回溯引用在替换操作中的应用

正则表达式还可以用来完成各种复杂的替换操作。

我们刚才讲过,回溯引用语法在不同的正则表达式实现里有很大的差异:JavaScript 用户需要用$来代替\;

表 8-1 用来进行大小写转换的元字符

◆ 第 9 章 前后查找

前后查找(lookaround,对某一位置的前、后内容进行查找)

◆ 9.2 向前查找

,被匹配到的:并没有出现在最终的匹配结果里;我们用?=向正则表达式引擎表明:只要找到:就行了,不要把它包括在最终的匹配结果里——用术语来说,就是“不消费”它。

在使用向前查找的时候,正则表达式分析器将向前查找并处理:匹配,但不会把它包括在最终的搜索结果里。模式.+(:)查找到并且匹配结果包含:,模式.+(? =:)查找到但匹配结果不包含:。

任何一个子表达式都可以转换为一个向前查找表达式,只要给它加上一个?=前缀即可。在同一个搜索模式里可以使用多个向前查找表达式,它们可以出现在模式里的任意位置(而不仅仅是出现在整个模式的开头——就像你们在上面看到的那样)。

◆ 9.3 向后查找

,? =被称为向前查找操作符

向后查找操作符是?<=。

分不清?=、? <=与其他?的话,有个简单的办法可以帮你分辨它们:有小于号的是向后查找操作符——你可以把这个小于号想像成一个箭头,它指向文本阅读方向的后

向前查找模式的长度是可变的,它们可以包含.和+之类的元字符,所以它们非常灵活。而向后查找模式只能是固定长度——这是一条几乎所有的正则表达式实现都遵守的限制。

◆ 9.5 对前后查找取非

向前查找和向后查找通常用来匹配文本,其目的是为了确定将被返回为匹配结果的文本的位置(通过指定匹配结果的前后必须是哪些文本)。这种用法被称为正向前查找(positive lookahead)和正向后查找(positive lookbehind)

前后查找还有一种不太常见的用法叫做负前后查找(negative lookaround)。负向前查找(negative lookahead)将向前查找不与给定模式相匹配的文本,负向后查找(negative lookbehind)将向后查找不与给定模式相匹配的文本。

表 9-1 各种前后查找操作符

◆ A.2 JavaScript

❑ exec:一个用来搜索一个匹配的 RegEx 方法。❑ match:一个用来匹配一个字符串的 String 方法。❑ replace:一个用来完成替换操作的 String 方法。❑ search:一个用来测试在某给定字符串里是否存在着一个匹配的 String 方法。❑ split:一个用来把一个字符串拆分为多个子串的 String 方法。❑ test:一个用来测试在某给定字符串里是否存在着一个匹配的 RegEx 方法。

g 选项激活全局搜索功能,i 选项让匹配操作不区分字母的大小写,这两个选项可以组合为 gi

m,支持多行字符串;s,支持单行字符串;x,忽略正则表达式模式里的空白字符。

$’将返回被匹配字符串前面的所有东西,$`将返回被匹配字符串后面的所有东西,$+将返回最后一个被匹配的子表达式,$&将返回被匹配到的所有东西。

站长推荐

《正则表达式必知必会》这本书讲的挺好的,简单易懂,推荐读一下。