正则表达式入门
正则表达式(Regular Expression)是强大、便捷、高效的文本处理工具; 提供强大的描述和分析文本
能力,配合特定的工具提供的额外支持,正则表达式可以添加、插入、删除、修改、分离和叠加各种
类型的文本和数据。
1. 正则表达式的思维框架
1.1 正则概述
- 元字符(metacharacters) : 由特殊字符构成,类似语法
- 文字(normal text) : 普通文本字符,类似于单词
- 正则由小的构建模块单元组成,每个单独的构建模块很简单,但是它们能够以无穷多种方式组合
- 正则表达式一般从左向右工作
1.2 检索文本文件 : Egrep
在指定正则表达式和需要检索的文件之后,egrep 会尝试用正则表达式来匹配每个文件的每一行,
并显示匹配的行。
- 单引号是 shell 中的
- 如果正则表达式不包括任何 egrep 支持的元字符,就成为一个简单的纯文本检索
- egrep 会在检查正则表达式之前去掉换行符
$ egrep 'regex' file
3. Egrep 元字符
^ 和 $
$ egrep '^cat' log.txt
$ egrep 'cat$' log.txt
$ egrep '^string$' file
$ egrep '^$' file
$ egrep '^'
[...]
$ egrep 'gr[ea]y' log.txt
[a-z][A-Z][1-9][A-Fa-f0-9]
[^...]
$ egrep '^[^0-9]' log.txt
$ egrep 'a[^b]' log.txt
[.]
$ egrep '03[-./]19[-./]76' file
$ egrep '03.19.76' file
[|]
$ egrep 'grey|gray' log.txt
$ egrep 'gr(e|a)y' log.txt
$ egrep 'gr[e|a]y' log.txt
$ egrep 'gr[ee|aa]y' log.txt
$ egrep '^(From|Subject|Date):'
$ egrep -i '^from:' log.txt
\<word\>
$ grep '\<init\>' log.txt
$ grep '\<init' log.txt
$ grep 'init\>' log.txt
-------------------------------------限定元素匹配次数 -------------------------------------
[element?]
$ egrep 'colou?r' file
'4th|4' 等同于 ‘4(th)?
+
*
<hr.+size.*=.*[0-9]+.*>
...{min,max}
[a-zA-z]{1,5}
(expression)...\1
\<([A-Za-z]+).+\1\>
([a-z])([0-9])\1\2
$ egrep 'www.baidu.com' file
$ egrep 'www\.baidu\.com' file
4. 基础知识拓展
4.1 差异化
- 不同的 egrep 版本之间存在着特性差异
- 不同的编程语言之间成存在着不同的差异
4.2 正则表达式的目标
从最宏观的角度看,一个正则表达式要么能够匹配给定的文本中某些字符,要么不能匹配;在编写
正则表达式的时候,必须进行权衡 : 匹配符合要求的文本,还是忽略不符合要求的文本。
4.3 更多例子
[a-zA-Z_][a-zA-Z_0-9]* # 匹配变量名标识符
[a-zA-Z_][a-zA-Z_0-9]{0,31} # 匹配变量名标识符并限制长度在 32 个字符
“[^"]*" # 匹配简单引号内的字符串, 不能匹配这种字符串 "\"string\""
\$([0-9]+|.)(\.\1)? # 匹配美元金额
$19
$.19
$19.2
$0.1
$19.999
$100
$ egrep -i '\<http://[a-z0-9_.:]+/[-a-z0-9_:@&?=+,.!/~*%$]*\.html?\>’ file # 匹配 http/html URL, 注意 '-' 必须在字符组开头,以免解析出错
$ egrep -i '\<http://[^]*\.html?\>' file # 相对简单匹配 URL
$ egrep -i '\<.*\>' file # 粗略匹配 HTML tag 标签,对于 <I>short</I> 无法处理
(1[012]|[1-9]):[0-5][0-9]\*(am|pm) # 匹配 12 小时制时间
09:12*pm
12:59*pm
12:59*am
00:13*am # 无法处理
5. 汇总
5.1 术语说明
术语 | 说明 |
---|
匹配(matching) | 指正则表达式在字符串中找到匹配的文本 |
元字符(metacharacter) | 一个字符是否为元字符, 取决与应用的具体情况 |
流派(flavor) | 不同的工具使用不同的正则表达式流派完成不同的任务, 每样工具支持的元字符和其他特性各不同 |
子表达式(subexpression) | 是整个正则表达式的一部分, 通常是括号内的表达式, 或者是由分号分隔的多选分支 |
5.2 egrep 的元字符总结
匹配单个字符的元字符
元字符 | 匹配对象 |
---|
. | 点, 单行模式 : 可以匹配任意字符(包括换行符); 非单行模式 : 不能匹配换行符 \n |
[…] | 字符组, 匹配单个列出的字符 |
[^…] | 排除型字符组, 匹配单个未列出的字符, ^ 必须在字符组的第一位 |
\char | 转义字符, 若 char 是元字符, 或转义序列无特殊含义时, 匹配 char 对应的普通字符, 在字符组内无意义 |
简记字符
元字符 | 匹配对象 |
---|
\t | 水平制表符 |
\v | 垂直制表符 |
\n | 换行符 |
\r | 回车符 |
\s | 任何”空白”字符(空格符、制表符、换行符和回车符) |
\S | 除 \s 之外的任何字符 |
\w | 就是 [a-zA-Z0-9], 也可以使用 \w+ 来匹配一个单词 |
\W | 除 \w 之外的任何字符, 也就是[^a-zA-Z0-9] |
\d | 数字, [0-9] |
\D | 除 \d 外的任何字符, 即 [^0-9] |
其他字符
元字符 | 匹配对象 |
---|
(?#…)和#… | 注释 |
\Q…\E | 引用字符的,可以使得其失去正则表达式的含义,而仅作为普通字符串 |
匹配模式修饰符
元字符 | 匹配对象 |
---|
i | 执行不区分大小写的匹配,例(?i)HTTP |
g | 执行一个全局匹配,即找到所有匹配而非一次匹配 |
m | 多行匹配模式 |
锚点(匹配位置的元字符)
元字符 | 匹配对象 |
---|
^ | 脱字符, 匹配一行的开头位置 |
$ | 美元符, 匹配一行的结束位置 |
A | 匹配一行的开头位置 |
z | 匹配一行的结束位置 |
Z | 绝对行尾 |
\<、\b | 单词分界符, 匹配单词的开始位置 |
>、\b | 单词分界符, 匹配单词的结束位置 |
\B | 匹配非单词边界 |
(?=…) | 肯定顺序环视,子表达式能够匹配右侧文本 |
(?!…) | 否定顺序环视,子表达式不能匹配右侧文本 |
(?<=…) | 肯定逆序环视,子表达式能够匹配左侧文本, 从右向左看文本, 例如 (?<=d) 如果当前位置的左边是一个数字, 则匹配成功 |
(? | 否定逆序环视,子表达式不能匹配左侧文本 |
多行文本模式(增强的行锚点模式)
元字符 | 匹配对象 |
---|
^ | 可以匹配字符串开头(字符串的开始位置),也可以匹配行的开头(即换行符\n之后的位置) |
$ | 可以匹配字符串结尾(字符串的结束位置), 也可以匹配行的结尾(即换行符\n之前的位置) |
\A | 匹配绝对行首 |
\z | 匹配绝对行尾 |
提供计数功能的元字符(贪婪模式)
元字符 | 匹配对象 |
---|
? | 问号,容许匹配一次,但非必须 |
* | 星号,0~N 可以匹配任意多次, 也可以不匹配 |
+ | 加号,1~N 至少需要匹配一次,也可以余部多次 |
{n} | 匹配指定次数 |
{n,} | 匹配指定次数以上 |
(min,max) | 区间量词,min~max 至少需要 min 次,至多容许 max 次 |
分组、捕获、条件判断和控制
元字符 | 匹配对象 |
---|
| | 或符号, 匹配任意分隔的表达式 |
(…) | 括号, 1. 限定多选构造的范围; 2. 分组以标注量词作用的元素; 3. 为反向引用”捕获”文本 |
\1…\n | 反向引用, 匹配之前的第一个…第N个括号内的字表达式匹配的文本 |
(?:…) | 仅用于分组的括号,不捕获文本 |
(?…) | 命名捕获, 可以通过名称直接引用捕获的内容\k<Name> |
(?>…) | 固化分组,匹配完成后抛弃所有备选状态,无法回溯 |
*、+、?、(num,num) | 贪婪模式, 优先匹配量词, 量词会尽量地吃,直到由于吃得太多,导致后面没法匹配,才吐出来一个 |
*?、+?、??、(num,num)? | 非贪婪模式, 忽略优先量词, 让量词尽可能少吃, 一但后面的表达式能够匹配就不吃了 |
*+、++、?+、(num,num)? | 占用优先量词,会尽量地吃, 并且不会交还已匹配的字符 |
?if then else | 条件判断, (?(?=regex)then |