一、正则表达式的重点有三:特殊字符、限定字符、定位符
- 特殊字符:勿忘加上转义符’’
- 限定字符:限定字符出现的次数,掌握它也就get了精华,麻麻再也不用担心我读不懂漂亮的表达式了。
- 定位符:稍加理解,就能get到的好技巧
二、常用的核心知识概要介绍
-
字符匹配:正则表达式可以匹配特定的字符。例如,字符 a 可以匹配字符串中的 a 字符。
-
字符类:使用字符类可以匹配一组字符中的任意一个字符。例如,字符类 [abc] 可以匹配 a、b 或 c。
-
范围类:范围类是一种特殊的字符类,它可以匹配某个范围内的字符。例如,字符类 [0-9] 可以匹配任意一个数字字符。
-
量词:量词用于指定字符或字符类出现的次数。例如,a+ 表示 a 可以连续出现一次或多次,b{2,4} 表示 b 可以连续出现2次到4次。
-
边界匹配:边界匹配用于限制匹配发生的位置。例如,^ 表示匹配行的开头,$ 表示匹配行的结尾。
-
转义字符:某些字符在正则表达式中具有特殊含义,如果想匹配它们本身,需要使用反斜杠 \ 进行转义。例如,., \, ( 等。
-
分组:使用括号 () 可以将表达式分组,形成一个捕获组。捕获组可以用于后续操作,比如提取匹配的内容。
-
非贪婪匹配:默认情况下,正则表达式是贪婪的,会尽可能多地匹配字符。如果需要非贪婪匹配,可以在量词后面加上 ?。
-
或操作:使用 | 可以实现或操作,匹配两个或多个表达式中的任意一个。
-
转义序列:正则表达式中有一些特殊的转义序列,例如 \d 表示匹配任意数字,\w 表示匹配任意字母、数字或下划线,\s 表示匹配任意空白字符等。
三、常用的核心知识详细介绍
1.字面量字符:
例如,a 匹配字符 “a”。
2.字符类:
方括号 [ ] 用于定义一个字符类。例如,[abc] 匹配字符 “a”、“b” 或 “c”。
还可以使用连字符 - 定义一个字符范围。例如,[a-z] 匹配小写字母。
3.量词:
.(句点)用来表示匹配任意单个字符,除了换行符 \n。换句话说,.可以匹配任何一个字符,包括字母、数字、符号等,但不包括换行符。
* 表示匹配零个或多个前面的元素。
+ 表示匹配一个或多个前面的元素。
? 表示匹配零个或一个前面的元素。
{n} 表示匹配恰好 n 个前面的元素。
{n,} 表示匹配至少 n 个前面的元素。
{n,m} 表示匹配至少 n 个且不超过 m 个前面的元素。
4.特殊字符:
\d 匹配任意数字。
\D 匹配任意非数字字符。
\w 匹配任意字母、数字或下划线。
\W 匹配任意非字母、数字或下划线字符。
\s 匹配任意空白字符(空格、制表符、换行符等)。
\S 匹配任意非空白字符。
5.锚点:
^ 匹配输入字符串的开始位置。
$ 匹配输入字符串的结束位置。
6.转义字符:
通过使用反斜杠 \ 来转义特殊字符。例如,\. 匹配点号 “。”
7.选择符:
| 表示选择符,用于匹配多个模式中的一个。例如,cat|dog 匹配 “cat” 或 “dog”。
8.零宽断言
零宽断言(Zero-width assertions)是正则表达式中的一种特殊模式,用于在匹配过程中指定一个位置,而不是具体的字符。它们被称为“零宽”是因为它们不会消耗实际的字符,只是检查匹配的位置。
以下是一些常见的零宽断言:
-
正向肯定预查(Positive Lookahead):(?=…)。它用于在当前位置向前查找,确保后面的模式能匹配成功,但不会消耗实际字符。
例如,正则表达式foo(?=bar)
会匹配后面跟着 “bar” 的 “foo”,但不会包括 “bar” 这部分。 -
正向否定预查(Negative Lookahead):(?!..)。它用于在当前位置向前查找,确保后面的模式不会匹配成功,但不会消耗实际字符。
例如,正则表达式foo(?!bar)
会匹配后面不跟着 “bar” 的 “foo”。 -
反向肯定预查(Positive Lookbehind):(?<=…)。它用于在当前位置向后查找,确保前面的模式能匹配成功,但不会消耗实际字符。
例如,正则表达式(?<=foo)bar
会匹配前面跟着 “foo” 的 “bar”,但不会包括 “foo” 这部分。 -
反向否定预查(Negative Lookbehind):(?<!..)。它用于在当前位置向后查找,确保前面的模式不会匹配成功,但不会消耗实际字符。
例如,正则表达式(?<!foo)
bar 会匹配前面不跟着 “foo” 的 “bar”。
零宽断言在正则表达式中非常有用,可以用于更精确地指定匹配的位置,而不会捕获或消耗实际的字符。这对于一些复杂的模式匹配和替换操作非常有帮助。然而,需要注意的是,并非所有的正则表达式引擎都支持零宽断言,因此在使用时需要检查所使用的正则表达式引擎的兼容性。
9.捕获组
捕获组(Capture Group)是正则表达式中一种特殊的语法,用于捕获和提取匹配的部分文本。通过使用括号将要捕获的内容括起来,可以创建一个捕获组。
以下是一些关于捕获组的详细介绍:
-
捕获组语法:使用圆括号 ( ) 来创建捕获组。例如,(abc) 表示一个捕获组,它可以匹配并捕获连续的 “abc” 字符串。
-
提取匹配的内容:捕获组可以从匹配的文本中提取出特定的部分。在匹配成功后,可以通过索引或名称来获取捕获组的值。
-
索引捕获组:每个捕获组都有一个索引,从 1 开始递增。可以使用索引来引用捕获组的值。例如,如果有一个正则表达式 (ab)(cd) 匹配了文本 “abcd”,那么捕获组 1 将包含 “ab”,捕获组 2 将包含 “cd”。
-
命名捕获组:捕获组也可以通过指定名称来标识。使用 (?pattern) 的语法来创建一个命名捕获组。例如,(?ab) 将创建一个名为 “group1” 的捕获组。
-
引用捕获组:捕获组还可以在正则表达式中被引用。使用 \数字 或 \k 的语法来引用先前捕获的组。例如,如果捕获组 1 匹配了 “ab”,则可以使用 \1 来引用该捕获组。
-
替换捕获组:捕获组可以在替换操作中使用。在替换字符串中,可以使用 $数字 或 ${name} 的语法来引用捕获组的值。这样可以在替换过程中将捕获的部分进行修改或重新排列。
10.贪婪匹配与非贪婪匹配
现在这些术语听起来都很吓人,其实这是正则匹配的两种模式,很容易解释:
- 贪婪匹配:尽可能匹配最长的字符串
- 非贪婪匹配: 尽可能匹配最短的字符串
举个例子:
aa<div>test1</div>bb<div>test2</div>cc
如果想要匹配一个完整的div,贪婪模式的结果为:
<div>test1</div>bb<div>test2</div>
非贪婪模式的结果为:
<div>test1</div>
可以发现贪婪模式会匹配尽可能长的字符串,而非贪婪模式在第一次匹配成功后就会停止匹配。
如何区分两种模式
默认情况下匹配都是贪婪模式,如果要改成非贪婪模式,只需要量词后面加上一个问号?。
常用的量词有:
{m,n}
{m,}
?
*
+
这些默认都是贪婪模式,若改成非贪婪模式,只需这样:
{m,n}?
{m,}?
??
*?
+?
针对上面那个div的例子,贪婪模式的匹配表达式为:
<div>.*</div>
非贪婪模式的匹配表达式为:
<div>.*?</div>
贪婪模式/非贪婪模式总结
贪婪模式就是匹配最长的字符串,非贪婪模式就是匹配最短字符串。
默认情况下匹配都是贪婪模式,如果要改成非贪婪模式,只需要量词后面加上一个问号?。
使用贪婪模式还是非贪婪模式,这主要取决于我们的需求。但有一点,非贪婪模式的性能一定是高于贪婪模式的。