正则表达式(Regular Expression)是表示搜索模式的字符串,常缩写成 Regex 或 Regexp。它常用于匹配、查找和替换文本中的字词。此外,我们可以测试文本是否符合我们设置的规则。
锚点:
^:匹配字符串或行的开头。$:匹配字符串或行的末尾。\b:匹配单词的开头或末尾。\B:匹配不在单词开头或末尾的位置。字符类:
[abc]:匹配不在集合中的任意字符。[a-z]:匹配两个字符之间的任意字符,包括它们本身。.:匹配除换行符外的任意字符。\w:匹配字母、数字或下划线字符。\W:匹配除字母、数字和下划线之外的任意字符。\d:匹配所有数字字符。\D:匹配除数字外的任意字符。\s:匹配所有空白字符。\S:匹配除空白字符以外的任意字符。标志:
g:确保表达式不会在检索到第一个匹配项时停止,即全局匹配。i:使表达式忽略大小写。m:如果不启用,^ 和 $ 只匹配首行字符串的开始和结束,而不会单独匹配每一行。量词与分支:
*:表达式匹配零个或多个。+:表达式匹配一个或多个。{1,3}:表达式匹配指定范围的位数,区间为左闭右闭。{1,}:表达式至少匹配的位数。?:使 ? 前面的字符可选,即可以有或没有(零次或一次)。|:类似于「或」,用于匹配多种符合条件的表达式之一。组和引用:
():使表达式分组。\1:引用表达式的分组,数字表示为第几个分组。(?:):创建无法引用的非捕获分组。它不是捕获分组,所以不能使用 \1 这种反向引用操作。零宽断言:
(?=):正向先行断言,就是断言后面的字符是否满足断言指定的模式,满足则匹配成功。(?!):负向先行断言,就是断言后面的字符是否满足断言指定的模式,不满足则匹配成功。(?<=):正向后行断言,就是断言前面的字符是否满足断言指定的模式,满足则匹配成功。(?<!):负向后行断言,就是断言前面的字符是否满足断言指定的模式,不满足则匹配成功。^(字符串或行的开头)^:匹配字符串或行的开头。
示例一:
an answer or a question/^\w+/g$(字符串或行的末尾)$:匹配字符串或行的末尾。
示例一:
an answer or a question/\w+$/g\b(单词边界)\b:匹配单词的开头或末尾。
示例一:
two questions or three questions/tions\b/g示例二:
two questions or three questions/\bqu/g示例三:
two questions or three questions/\bes/g\B(非单词边界)\B:匹配不在单词开头或末尾的位置。
示例一:
an answer or a question/n\B/gn。示例二:
an answer or a question/\Bn/gn。[abc](字符集)[abc]:匹配集合中的任意字符。
示例一:
car ber bir bor bd bood boedr bur/b[oe]r/gb、结尾是 r、中间 一个 字符是 o 或 e 的字符串。[^abc](否定字符集)[abc]:匹配不在集合中的任意字符。
示例一:
car ber bir bor bd bood boedr bur/b[^oe]r/gb、结尾是 r、中间 一个 字符不是 o 或 e 的字符串。[a-z](范围)[a-z]:匹配两个字符之间的任意字符,包括它们本身。
示例一:
abcdef b ec emc/[b-e]/g.(点).:匹配除换行符外的任意字符。
示例一:
hi012_-!?/./g\w(单词)\w:匹配字母、数字或下划线字符。
示例一:
hi 01?2 _-!?/\w/g\W(非单词)\W:匹配除字母、数字和下划线之外的任意字符。
示例一:
hELLo 01??2 _-!?/\W/g\d(数字)\d:匹配所有数字字符。
示例一:
+144-(22)-13=0x6D/\d/g\D(非数字)\D:匹配除数字外的任意字符。
示例一:
+144-(22)-13=0x6D/\D/g\s(空白符)\s:匹配所有空白字符。
示例一:
one two ./\s/g\S(非空白符)\S:匹配除空白字符以外的任意字符。
示例一:
one two ./\S/gg(全局匹配)g:确保表达式不会在检索到第一个匹配项时停止,即全局匹配。
示例一:
cat dog&cat/cat/g示例二:
cat dog&cat/cat/i(忽略大小写)i:使表达式忽略大小写。
示例一:
CaT dog&cat/cat/gim(多行)m:如果不启用,^ 和 $ 只匹配首行字符串的开始和结束,而不会单独匹配每一行。
示例一:
文本:
a white cat
a black cat
正则:/^a/g
解释:全局匹配字符串开头是 a 的字符(不能匹配每行字符串开头是 a 的字符)。
示例二:
文本:
a black cat
a white cat
正则:/at$/g
解释:全局匹配字符串结尾是 at 的字符(不能匹配每行字符串结尾是 at 的字符)。
示例三:
文本:
a white cat
a black cat
正则:/^a/gm
解释:全局匹配整个字符串 每行 开头是 a 的字符。
示例四:
文本:
a white cat
a black cat
正则:/at$/gm
解释:全局匹配整个字符串 每行 结尾是 at 的字符。
*(至少匹配零个)*:表达式匹配零个或多个。
示例一:
bp bep beep/be*p/g+(至少匹配一个)+:表达式匹配一个或多个。
示例一:
bp bep beep/be+p/g{1,3}(指定范围匹配){1,3}:表达式匹配指定范围的位数,区间为左闭右闭。
示例一:
bp bep beep/be{1,2}p/g{1,}(至少匹配次数){1,}:表达式至少匹配的位数。
示例一:
bp bep beep beeep/be{1,}p/g?(指定字符可选)?:使 ? 前面的字符可选,即可以有或没有(零次或一次)。
示例一:
color colour/colou?r/g示例二:
color colour cor/co(lo)?r/g|(或分支)|:类似于「或」,用于匹配多种符合条件的表达式之一。
示例一:
fat, cat, rat/(c|r)at/g 或者 /[cr]at/g()(捕获分组)():使表达式分组。
示例一:
hahaha, h, ha/(ha)+/g\1(引用)\1:引用表达式的分组,数字表示为第几个分组。
示例一:
hah, haa, dad, dada/(\w)a\1/g(\w) 匹配一个字母字符(包括大小写字母、数字和下划线),第二个字符为 a,反向引用 \1 表示引用第一个捕获组中匹配到的内容。该正则匹配字符 a 左右两个字符相等的字符串。示例二:
hah, haa, dad, woawo, dada/(\w+)a\1/g(\w+) 至少匹配一个字母字符,第二个字符为 a,反向引用 \1 表示引用第一个捕获组中匹配到的内容。示例三:
hah, haa, dad, wobwob, dada/(\w+)([ab])\1\2/g(?:)(非捕获组)(?:):创建无法引用的非捕获分组。它不是捕获分组,所以不能使用 \1 这种反向引用操作。
示例一:
hahaha, hah, haaha/(?:ha)+/gha 的字符串。(?=)(断言后面满足给定模式)(?=):正向先行断言,就是断言后面的字符是否满足断言指定的模式,满足则匹配成功。
示例一:
1st, 2nd, 3pc, 4nd/\d(?=nd)/gnd 的那个数字。在 1st 中有数字 1,但是在正向先行断言时,检查到的第一个字符为 s,与断言中的 n 不匹配,这时会停止匹配。正向先行断言记忆:看后面的字符是不是(
?)等于(=)断言中的模式,等于则匹配成功。
?!(断言后面不满足给定模式)(?!):负向先行断言,就是断言后面的字符是否满足断言指定的模式,不满足则匹配成功。
示例一:
1st, 2nd, 3pc, 4ne/\d(?!nd)/gnd 的那个数字。负向先行断言记忆:看后面的字符是不是(
?)不等于(!)断言中的模式,不等于则匹配成功。
?<=(断言前面满足给定模式)(?<=):正向后行断言,就是断言前面的字符是否满足断言指定的模式,满足则匹配成功。
示例一:
#1, $2, %3/(?<=%)\d/g% 的那个数字。正向后行断言记忆:看前面(
<)的字符是不是(?)等于(=)断言中的模式,等于则匹配成功。
?<!(断言前面不满足给定模式)(?<!):负向后行断言,就是断言前面的字符是否满足断言指定的模式,不满足则匹配成功。
示例一:
#1, $2, %3/(?<!%)\d/g% 的那个数字。负向后行断言记忆:看前面(
<)的字符是不是(?)不等于(!)断言中的模式,不等于则匹配成功。
有时候我们写的代码会不规范,比如指针变量可以写成 int* a; 或者 int * a;,普通变量可以写成 int a;。
如何写一个正则表达式,来匹配所有不规范,并格式化它呢?
要规范化的代码:
1 | typedef struct job{ |
正则表达式:/(?<=\w)\s*(?<!\/)\**\s+/gm
在线练习,这个正则表达式的含义是:
(?<=\w):断言前面是一个单词字符。
\s*:匹配零个或多个空白字符。
(?<!\/):断言前面不是斜杠字符。
\**:匹配零个或多个星号字符。
\s+:匹配一个或多个空白字符。
综合起来,这个正则表达式的作用是匹配在单词字符后面,按顺序地:可以有或没有空格、可以有或没有星号(不能是斜杠后面的星号)、至少一个空格。
结果图:

格式化替换:
1 | import re |
替换后结果:
1 | typedef struct job{ |
参考资料: