正则表达式入门
在注册账号设置密码时,通常会有大小写、特殊字符、长度的限制,不合法的输入则会出现提示;学生认证时,填写教育邮箱,会有.edu相关后缀的检查;在搜索文件时,如果需要图片,你可能就会筛选.jpg .png等后缀,如果只想要文本文本,你可能就只需要.txt .doc .docx后缀的文件。
在上述的场景中,都可以看到正则表达式的影子。
正则表达式(Regular Expression,简称 Regex 或 RegExp)是一种用来匹配字符串中字符组合的模式。
涉及到字符串、文本的场景,基本上都会用到正则表达式。正则表达式提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据。
在编程时,涉及到字符串处理的,会用到正则表达式,基本上每个语言都支持正则表达式;在一些文本处理工具,或者搜索工具软件比如evething,也可能用到正则表达式。
初步认识
不同编程语言的语法和标准库存在差别,但是正则表达式语法式通用的。
对于以下一段文字:
RegExr was created by gskinner.com.Edit the Expression & Text to see matches. Roll over matches or the expression for details. PCRE & JavaScript flavors of RegEx are supported. Validate your expression with Tests mode.The side bar includes a Cheatsheet, full Reference, and Help. You can also Save & Share with the Community and view patterns you create or favorite in My Patterns.Explore results with the Tools below. Replace & List output custom results. Details lists capture groups. Explain describes your expression in plain English.zoo、tools。
如果想寻找单个字母,比如o,那么正则表达式(Regex)写成o即可。这可以查找出所有的o。
如果想寻找某个字母连续出现一次或者多次,比如oo ooooo等,则Regex可写成o+,这可以查找所有o,oo,ooo…的排列。
此外,如果想查找多种单个字母,那么Regex的写法需要加上[],而非简单的字母组合。
比如寻找所有的
a,A,o这三个字母,正确的写法是[aoA],Regex是区分大小写的。当然这种写法按照全排列计算,有 A 3 3 A^3_3 A33种,即 3! 个写法,任取一个即可。
但是使用aoA这种不加括号[]的写法,匹配的则是“aoA”这个“单词”。常用的比如查找“apple”,“banana”。
至于[aoA]+这种写法,则是匹配一个「块」,这个块可以是单个字符,也可以是这几个字符的组合。当然,如果这几个字符的组合中插入了其他字符,则不属于这种「块」。
很常见的一些表达有:
- 字符类:如 [abc] 表示匹配 a、b 或 c 中的任意一个字符。
- 量词:如 *(零次或多次)、+(一次或多次)、?(零次或一次)。
- 边界匹配:如 ^(行的开始)、$(行的结束)。
- 分组:使用圆括号 () 来创建一个分组。
关于其他更多常用的用法如下:
基础语法整理(表)
可以在 https://regexr.com 中进行测试。
| 分类 | 语法 / 符号 | 说明 | 示例 |
|---|---|---|---|
| 基础字符匹配 | 普通字符(a ~ z / A ~ Z / 0 ~ 9) | 以块的形式,直接匹配相应的字母数字组合。 | s匹配到s, ac 匹配的是字符串中的 ac |
元字符(.^$*+?{0}|\) | 和编程一样,这些字符有特殊含义,需加 \ 转义 才能匹配自身 | 匹配 . 需写 \.;匹配 \ 需写 \\ | |
. | 通配符,匹配除换行符(\n \r)外的任意 单个 字符。等价于[^\n\r] | a.c 匹配 abc, adc, a1c等,但是匹配不到alsc | |
| 预定义字符类 | \d | 等价于 [0-9],匹配数字 | \d{3} 匹配三位数字,比如 123, 456等 |
\D | 等价于 [^0-9],匹配非数字 | \D+ 匹配多位非数字 abc, @#$等 | |
\w | 等价于 [a-zA-Z0-9_],匹配字母、数字、下划线。 | \w匹配任意一个(alphanumeric&underscore)。\w{5} 匹配5位的字母数字下划线组合,如 user1, name_等 | |
\W | 等价于 [^a-zA-Z0-9_],匹配非字母数字下划线字符。 | \W 匹配 @, #, \space等 | |
\s | 匹配空白字符(空格\space、制表符\t、换行符 \n 等) | a\sb 匹配 a b, a\tb等 | |
\S | 匹配非空白字符。 | \S+ 匹配多位 hello, 123@等 | |
| 字符类(自定义) | [abc] | 匹配括号内任意一个字符 | [xyz] 匹配 x,y, z |
[^abc] | 匹配除括号内字符外的任意字符(^ 表示否定) | [^xyz] 匹配 a, 1, @等 | |
[a-z]/[A-Z]/[0-9] | 匹配指定范围的字符 | [a-z0-9] 匹配小写字母和数字 | |
| 量词(匹配次数) | * | 匹配前面的元素 0 次或多次 (贪婪模式) | ab* 匹配 a, ab, abb等 |
+ | 匹配前面的元素 1 次或多次 | ab+ 匹配 ab, abb, abbb等 | |
? | 匹配前面的元素 0 次或 1 次;加在量词后变为非贪婪模式 | ab? 匹配 a, ab;a.*?b 匹配 aab 中的 aab(非贪婪) | |
{n} | 精确匹配前面的元素 n 次 | a{3} 匹配 aaa | |
{n,} | 匹配前面的元素至少 n 次 | a{2,} 匹配 aa, aaa, aaaa等 | |
{n,m} | 匹配前面的元素 n 到 m 次(包含边界) | a{2,4} 匹配 aa, aaa, aaaa | |
| 定位符(匹配位置) | ^ | 匹配字符串开头(多行模式下匹配每行开头) | ^abc 匹配以 abc 开头的字符串 |
$ | 匹配字符串结尾(多行模式下匹配每行结尾) | abc$ 匹配以 abc 结尾的字符串 | |
\b | 匹配单词边界(字母与非字母交界处) | \babc\b 匹配独立单词 abc(不匹配 abcd, xabc) | |
\B | 匹配非单词边界 | \Babc\B 匹配 xabcx 中的 abc(不匹配独立单词 abc) | |
| 分组与捕获 | (pattern) | 分组,将 pattern 视为整体;默认捕获分组内容 | (abc){2} 匹配 abcabc;(a)(b)\1\2 匹配 abab |
(?:pattern) | 非捕获组,仅分组不捕获(不占用组编号) | (?:abc){2} 匹配 abcabc,但无法通过\1引用 abc | |
| 断言(条件匹配) | (?=pattern) | 正向先行断言:匹配后面紧跟 pattern 的内容(不占字符) | abc(?=123) 匹配后面是 123 的 abc(如 abc123 中的 abc) |
(?!pattern) | 负向先行断言:匹配后面不紧跟 pattern 的内容 | abc(?!123) 匹配后面不是 123 的abc(如 abc456 中的 abc) | |
(?<=pattern) | 正向后行断言:匹配前面是 pattern 的内容 | (?<=123)abc 匹配前面是 123 的 abc(如 123abc 中的 abc) | |
(?<!pattern) | 负向后行断言:匹配前面不是 pattern 的内容 | (?<!123)abc 匹配前面不是 123 的 abc(如 456abc 中的abc) | |
| 逻辑或 | pattern1|pattern2 | 匹配 pattern1 或 pattern2(优先级低,需结合分组) | abc|def 匹配 abc 或 def;a(b|c)d 匹配abd 或 acd |
