漫谈正则表达式(regular expression)
1. 几个前提
本文整理了 Linux、SQL、Python 与正则表达式相关的内容,人生苦短,简单粗暴。由于是漫谈,范围局限于 Linux 的 bash,SQL(包括 MS SQLSERVER/MYSQL/ORACLE),Python 正则表达式相关内容;并没有具体区分,因为好多内容是相通的,直接漫谈即可。
2. 从 Linux 的角度去漫谈
概述:1+1=2,这是小学学过的一个公式,可以理解为是一种表示法;而正则表达式也是一类的“表示法”,这种表示法主要偏向于处理字符串相关。
先从 helloworld 谈,print(“HelloWorld”),这是某一种程序支持的一种“表示法”,可以输出字符串;而正则表达式的这种“表示法”呢,也需要程序的支持。
划重点:正则表达式可以通过一些特殊符号的辅助,并且这种表示法需要特定程序的支持,那么该程序就可以用来作为正则表达式的字符串处理之用。
举例:Linux 的 grep、sed、awk 等等程序。数据库的 SQL 中的 REGEXP,python 中的 re,这类型的程序+表达式,可以成为正则表达式的处理系统。
3. 由浅入深
再谈正则表达式之前,先谈一谈通用的“表示法”,比如,linux 中 bash 的通配符,sql 中的 like,python 中的通配符。
暂且把这种最基础的表示法,称为“通配符”,这些通配符可以理解为基础的支持,即所用的程序都可以支持,比如linux 中的 ls、cp、各种管道、肯定也包括支持正则表达式的程序、等等各种各样的巴拉巴拉乱七八糟的东西。
3.1 Linux 最基础的通配符:
符号 | 含义 | 举例 |
---|---|---|
* | 代表【0 到无穷多个】任意字符 | |
? | 代表【一定有一个】任意字符 | |
[ ] | 代表一定有一个在括号内的任意字符 | |
[ - ] | [0-9]代表 0 到 9 之间所有数字 | |
[^ ] | 反向选择 | [^abc] 代表一定有一个字符,只要是非 a、b、c 的其他字符就接受 |
3.2 SQL 最基础的通配符(一般用在模糊查询):
此时可以理解为 SQL like 的操作符:LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。
符号 | 含义 | 举例 |
---|---|---|
% | 代表【0 到无穷多个】任意字符 | |
_ (下划线) | 代表一个字符 | |
[ ] | 代表一定有一个在括号内的任意字符 | |
[^ ] 或 [!] | 反向选择 | [^abc] 代表一定有一个字符,只要是非 a、b、c 的其他字符就接受 |
看到了没?linux 的 bash 通配符,和 SQL 的 like 通配符,还是不一样的,有差异。
并且,MS SQLSERVER、MySQL、Oracle 三者支持的通配符都不一样,需要查找:MySQL 、SQLite 只支持 % 和 _ 通配符,不支持 [^charlist] 或 [!charlist] 通配符( MS Access支持,微软 office 对通配符一直支持良好,但微软有时候的通配符不支持 %,而是 *,具体看对应软件说明)。
通配符和正则不是一回事。MySQL 和 SQLite 会把 like ‘[xxx]yyy’ 的中括号当成普通字符,而不是通配符。Oracle 一般支持度比较好。
3.3 Python 通配符
Python 毕竟是程序设计语言,支持的通配符非常多,多的让人烦躁!具体在正则表达式中看。网上找一找吧
Python 常用通配符:
符号 | 含义 | 举例 |
---|---|---|
* | 代表【0 到无穷多个】任意字符 | |
? | 代表一个字符 | |
[ ] | 代表一定有一个在括号内的任意字符 | |
[^ ] 或 [!] | 反向选择 | [^abc] 代表一定有一个字符,只要是非 a、b、c 的其他字符就接受 |
显然,phton 的通配符和 linux 的 bash 通配符大致相同,也就 SQL 有点变态!
4. Linux 处理正则表达式程序
汇总信息可参见如下思维导图:
列出一部分基本的正则表达式基础集:
符号 | 含义 | 举例 |
---|---|---|
^字符串 | 代表待查这个字符串在行首 | |
字符串^ | 代表待查这个字符串在行尾 | |
. | 代表一定有一个任意字符 | 请联想通配符,是不一样的 |
\ | 反向选择 | [^abc] 代表一定有一个字符,只要是非 a、b、c 的其他字符就接受 |
* | 类似通配符的*,即 0 到无穷多 | |
[字符串] | 在集合里列出想要选取的字符 | |
[n1-n2] | 字符范围,比如 A-Z 、a-z、0-9 | |
[^字符串] | 反向的,pass 了 | |
\{n,m\} | 有点复杂,看例子吧 | 范例:在 g 与 g 之间有 2 个到 3 个 o存在的字符串,即 goog 和 goooggrep -n ‘go\{2,3\}g’ 文件 |
可以先了解基本的功能,然后遇到了具体信息再查找具体的参数。
一些具体的正则表达式程序:
程序 | 含义 |
---|---|
grep | 就不说了,是查看和搜索功能 |
sed | 显示及操纵文件的内容(以行为单位) |
Awk | 对文本的数据处理工具 |
5. SQL 的正则表达式程序
5.1 SQL SERVER 使用正则表达式
较麻烦,须构建一个提供 regex 功能的 clr 过程;
5.2 MySQL 正则表达式
可以通过 LIKE …% 来进行模糊匹配。MySQL 同样也支持其他正则表达式的匹配, MySQL 中使用 REGEXP 操作符来进行正则表达式匹配。
下表中的正则模式可应用于 REGEXP 操作符中:
符号 | 含义 | 举例 |
---|---|---|
^字符串 | 某个字段的开始位置 | 和 linux 正则类似 |
字符串^ | 某个字段的结束位置 | 和 linux 正则类似 |
. | 任意单个字符 | 例如,zo* 能匹配 “z” 以及 “zoo”。*等价于{0,} |
* | 匹配前面的子表达式零次或多次 | 例 如 , zo* 能 匹 配 “zo” 以 及"zoo"。* 等价于{1,} |
[字符串] | 在集合里列出想要选取的字符 | 和 linux 正则类似 |
[^字符串] | 反向的,pass 了 | 和 linux 正则类似 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3 | ‘z|food’ 能 匹 配 “z” 或"food"。’(z|f)ood’ 则匹配 "zood"或 “food” |
{n} | n 是一个非负整数。匹配确定的 n 次 | ‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。 |
{n,m} | m 和 n 均为非负整数,其中 n <= m最少匹配 n 次且最多匹配 m 次。 |
5.3 Oracle 正则表达式
Oracle 正则表达式更复杂,Oracle 使用正则表达式离不开这 4 个函数:
函数名 | 意义 | 备注 |
---|---|---|
regexp_like | 只能用于条件表达式,和 like 类似,但是使用的正则表达式进行匹配 | |
regexp_substr | 和 substr 类似,用于拾取合符正则表达式描述的字符子串 | |
regexp_instr | 和 instr 类似,用于标定符合正则表达式的字符子串的开始位置 | |
regexp_replace | 和 replace 类似,用于替换符合正则表达式的字符串 |
而正则表达式的操作符更多,基础的操作符,请参见 MYSQL 正则表达式。
参考:https://www.cnblogs.com/lxl57610/p/8227599.html
6. Python 正则表达式
Python 的正则表达式的操作符是最丰富的:
正则表达式 代表的匹配字符
[0-9] 0123456789 任意之一
[a-z] 小写字母任意之一
[A-Z] 大写字母任意之一
\d 等同于[0-9]
\D 等同于[^0-9]匹配非数字
\w 等同于[a-z0-9A-Z_]匹配大小写字母、数字和下划线
\W 等同于[^a-z0-9A-Z_]等同于上一条取非
元字符 说明
. 代表任意字符
| 逻辑或操作符
[ ] 匹配内部的任一字符或子表达式
[^] 对字符集和取非
- 定义一个区间
\ 对下一字符取非(通常是普通变特殊,特殊变普通)
* 匹配前面的字符或者子表达式 0 次或多次
*? 惰性匹配上一个
+ 匹配前一个字符或子表达式一次或多次
+? 惰性匹配上一个
? 匹配前一个字符或子表达式 0 次或 1 次重复
{n} 匹配前一个字符或子表达式
{m,n} 匹配前一个字符或子表达式至少 m 次至多 n 次
{n,} 匹配前一个字符或者子表达式至少 n 次
{n,}? 前一个的惰性匹配
^ 匹配字符串的开头
\A 匹配字符串开头
$ 匹配字符串结束
[\b] 退格字符
\c 匹配一个控制字符
\d 匹配任意数字
\D 匹配数字以外的字符
\t 匹配制表符
\w 匹配任意数字字母下划线
\W 不匹配数字字母下划线
举例:
import re key = r"saas and sas and saaas" p1 = r"sa{1,2}s" pattern1 = re.compile(p1) print pattern1.findall(key) 输出: ['saas', 'sas']
复制
import re re.match #从开始位置开始匹配,如果开头没有则无 re.search #搜索整个字符串 re.findall #搜索整个字符串,返回一个 list
复制
《正则表达式专题2019.6.8》文档下载:https://www.modb.pro/doc/2409