【编程】正则表达式语法 零基础快速入门掌握
前言
本文正确 "食用" 方法:
1、通过功能分类,查看表达式语法及说明(适合新手)
2、直接搜索表达式语法,查看语法说明(适合备忘速查)
3、可以配合正则表达式工具 "Match Tracer" 一起使用
4、Python语言使用正则表达式,可以参考这篇文章
修饰符
指定匹配模式:全局匹配、多行匹配、区分大小写等
//i g m s
i(ignore) //搜索时不区分大小写:A 和 a 没有区别 g(global) //全局匹配,查找所有的匹配项 m(more) //多行匹配,使边界字符‘^’和‘$’匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾 s //使特殊字符点号‘.’,包含换行符‘\n’(默认情况下:‘.’只匹配除换行符‘\n’之外的任何字符)
转义符
将后面的字符标记为原义字符、转义字符、特殊语法、向后引用等
//\ \r \n \f \t \v \cx
//======将后面的字符标记为:原义字符====== \ 表达式:“\[” 字符串:"123[456" 匹配字符串中的‘[’字符(该字符是正则语法的一部分,所以需要转义后才能匹配) //======将后面的字符标记为:转义字符====== \r 匹配一个回车符,等价于 \x0d 和 \cM \n 匹配一个换行符,等价于 \x0a 和 \cJ \f 匹配一个换页符,等价于 \x0c 和 \cL \t 匹配一个制表符。等价于 \x09 和 \cI \v 匹配一个垂直制表符。等价于 \x0b 和 \cK \cx 匹配由 x 指明的控制字符。例如:\cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之一。否则将 c 视为一个原义的 'c' 字符 //======将后面的字符标记为:特殊语法====== \s \S \b \B \d \D \w \W (详见字符匹配) //======将后面的字符标记为:向后引用====== \n (详见分组匹配)
字符匹配
匹配单个字符、多个字符(字符串)等
//^ $ . | [] \s \S \b \B \d \D \w \W \xn \un
^ 从字符串开头匹配。例如:'^123' 可以匹配 "123a456" 中的 "123" $ 从字符串结尾匹配。例如:'456$' 可以匹配 "123a456" 中的 "456" . 匹配除换行符(\n、\r)之外的任何单个字符 a|b 匹配 a 或 b。例如:'z|food' 能匹配 "z" 或 "food" [abc] 匹配“[]”中的任意一个字符。例如:'[abc]' 可以匹配 "plain" 中的 'a' [^abc] 匹配“[]”中以外的任意一个字符。例如:'[^abc]' 可以匹配 "plain" 中的'p'、'l'、'i'、'n' [a-z] 匹配指定范围内的任意字符。例如:'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符 [^a-z] 匹配指定范围以外的任意字符。例如:'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。 \s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] \S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] \b 匹配一个单词边界,单词和空格间的位置(匹配的单词后面 "有" 空格) 例如:"er\b" 可以匹配 "123er 456" 中的 "er" \B 匹配非单词边界,作用与‘\b’相反(匹配的单词后面 "没有" 空格) 例如:"er\B" 可以匹配 "123er456" 中的 "er" \d 匹配一个数字字符。等价于 [0-9] \D 匹配一个非数字字符。等价于 [^0-9] \w 匹配字母、数字、下划线。等价于'[A-Za-z0-9_]' \W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]' \xn 匹配一个"ASCII"字符,n = 十六进制"ASCII"编码,例如:"\x41" 可以匹配 "A" \un 匹配一个"UNICODE"字符,n = 十六进制"UNICODE"编码,例如:"\x6211" 可以匹配 "我"
重复匹配
重复匹配某个字符、字符串或指定范围内的字符
//* + ? {}
* 匹配前面的子表达式零次或多次。例如:zo* 能匹配 "z" 以及 "zoo"。等价于{0,} + 匹配前面的子表达式一次或多次。例如:'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。等价于 {1,} ? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 。等价于 {0,1} {n} n = 正整数。匹配 n 次。例如:'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o {n,} n = 正整数。至少匹配 n 次。例如:'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o {n,m} n = m = 正整数。n <= m。最少匹配 n 次且最多匹配 m 次。例如:"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?' //贪婪 当正则表达式中包含以上重复限定符时,在整个表达式能得到匹配的前提下,匹配尽可能 "多" 的字符。 例如:'123[a]+' 可以匹配 "123aaa456" 中的所有 "aaa" //非贪婪 在重复限定符后面加上问号"?",可以使整个表达式能得到匹配的前提下,匹配尽可能 "少" 的字符。 例如:'123[a]+?' 可以只匹配 "123aaa456" 中的一个 "a" *? 重复任意次, 但尽可能少重复 +? 重复1次或多次, 但尽可能少重复 ?? 重复0次或1次, 但尽可能少重复 {n,}? 重复n次以上, 但尽可能少重复 {n,m}? 重复n到m次, 但尽可能少重复
分组匹配
按不同的分组表达式,匹配字符串(类似C语言中"()"的作用)
//() (?:) (?=) (?<=) (?!) (?<!)
//分组() 小括号中的表达式被称为"分组",多个括号既多个分组,每一个分组会将匹配到的结果保存起来, 可以通过使用类似C语言中的数组下标对每个分组所匹配的结果进行引用。 下标0=整个表达式,下标1=第一个分组,依次类推。 表达式;1([a-z])([A-Z]) 匹配结果为:1aA 分组0 = “1aA” 分组1 = “a” 分组2 = “A” //反向引用 用于重复搜索前面某个分组匹配的文本,可以使用"\n"对表达式中的某一个分组值进行引用,n = 正整数。 表达式:1([a-z])([A-Z])\1 //使用"\1"对第一个分组结果进行引用 匹配结果为:1aAa //结尾的'a'来自于对分组1结果的引用 //分组命名 可以给某一个分组指定一个分组名称,语法 = "(?<name>[0-9])" 或 "(?'name'[0-9])"。 当反向引用这个分组内容时可以使用"\k<name>"进行引用(“name”可以是任意名称) 表达式:(?<name>[0-9])([a-z])\k<name>\1 //指定第一个"[0-9]"的分组名称为“name” 匹配结果为:1a1a //使用分组名称和下标对分组结果进行引用 //其它分组语法 以下语法不会保存分组匹配到的结果,也不会指定分组下标,所以不能用于反向引用 (?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号下标(无法使用\n对该分组进行引用) (?=exp) 匹配exp前面的位置,例如:"[0-9]+(?=a)" 能匹配字符串 "123a456" 前面的"123" (?<=exp) 匹配exp后面的位置,例如:"(?<=a)[0-9]+" 能匹配字符串 "123a456" 后面的"456" (?!exp) 匹配后面跟的不是exp的位置,例如:"[0-9]{3}(?!a)" 能匹配字符串 "123a456b" 后面的"456" (?<!exp) 匹配前面不是exp的位置,例如:"((?<!a)[0-9]{3}" 能匹配字符串 "a123b456" 后面的"456"
总结
正则表达式属于字典类型的知识,很少有人能完全记住语法灵活使用,只要记住几个功能分类,使用的时候多查多用就可以了。
参考
https://www.runoob.com/regexp/regexp-syntax.html
https://deerchao.cn/tutorials/regex/regex.htm#grouping