1.正则表达式入门

正则表达式入门

  正则表达式(Regular Expression)是强大、便捷、高效的文本处理工具; 提供强大的描述和分析文本
能力,配合特定的工具提供的额外支持,正则表达式可以添加、插入、删除、修改、分离和叠加各种
类型的文本和数据。

1. 正则表达式的思维框架

1.1 正则概述

  • 元字符(metacharacters) : 由特殊字符构成,类似语法
  • 文字(normal text) : 普通文本字符,类似于单词
  • 正则由小的构建模块单元组成,每个单独的构建模块很简单,但是它们能够以无穷多种方式组合
  • 正则表达式一般从左向右工作

1.2 检索文本文件 : Egrep

  在指定正则表达式和需要检索的文件之后,egrep 会尝试用正则表达式来匹配每个文件的每一行,
并显示匹配的行。

  1. 单引号是 shell 中的
  2. 如果正则表达式不包括任何 egrep 支持的元字符,就成为一个简单的纯文本检索
  3. egrep 会在检查正则表达式之前去掉换行符
$ egrep 'regex' file      

3. Egrep 元字符

# 行的起始和结束
^ 和 $                          # 行的起始位置和行的结束位置
$ egrep '^cat' log.txt          # 行开头 --> 第一个字符是c --> 紧接一个 a --> 再紧接一个 t 开头的行(这样理解有助于理解正则的内部逻辑)
$ egrep 'cat$' log.txt   

$ egrep '^string$' file         # 行开头 --> 紧接是 string --> 再接着结尾的行
$ egrep '^$' file               # 判断空行, 行开头 --> 紧接是行尾的行
$ egrep '^'                     # 行开头, 无意义, 因为每行都有行开头, 匹配每一行


# 字符组
[...]                           # 匹配一个列出的字符
$ egrep 'gr[ea]y' log.txt       # 以 gr开头, 接着是 e 或 a, 再接着是 y 的单词(gr[e|a]y)
[a-z][A-Z][1-9][A-Fa-f0-9]      # 可以使用字符组元字符 '-' 省略中间的序列字符范围, 只有在字符组内并而且不在字符组开头的 '-' 才会被解析成字符组元字符


# 排除型字符组
[^...]                          # 匹配一个未列出的字符, '^' 必须是字符组内的第一个字符
$ egrep '^[^0-9]' log.txt       # 行开头 --> 第一个字符是非数字的行
$ egrep 'a[^b]' log.txt         # 包含字符a --> 紧接着非 b 的行


# 用点匹配任意字符
[.]                             # 匹配任何字符, 在字符组之外
$ egrep '03[-./]19[-./]76' file # 该正则字符组内的 [-./] 都是普通字符, 只是用来表示范围, 并不是元字符
$ egrep '03.19.76' file         # 包含上一行的正则效果, 简洁但没有上一行精准


# 多选结构
[|]                             # "或" 元字符, 可以匹配任意长度的文本, 把不同的子表达式组合成一个总的表达式, 而这个总表达式又能够匹配任意的子表达式, 在字符组外使用
$ egrep 'grey|gray' log.txt     # 匹配 grey 或者 gray
$ 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):' # 开头是 From:、Subject: 或 Date: 的行


# 忽略大小写
$ egrep -i '^from:' log.txt     # 使用 egrep 的命令行参数 “-i” 表示进行忽略大小写匹配


# 单词分界符
\<word\>                        # \< 用来匹配单词的开头,\> 用来匹配单词的结尾
$ grep '\<init\>' log.txt       # 匹配 init 单词
$ grep '\<init' log.txt         # 匹配 init 开头的单词
$ grep 'init\>' log.txt         # 匹配 init 结尾的单词


-------------------------------------限定元素匹配次数 -------------------------------------
# 可选项元素(单\多选都可以)
[element?]                      # 表示容许出现?号之前紧邻的元素,但它的出现并非匹配成功的必要条件
$ egrep 'colou?r' file          # 单元素可选, c-->o-->l-->o-->[u?]-->r, [u?] 是否出现都可以
'4th|4' 等同于 ‘4(th)?           # 多个元素可选


# 其它量数
+                               # 加号表示之前紧邻的元素出现 1~N 次
*                               # 星号表示之前紧邻的元素出现 0~N 次
<hr.+size.*=.*[0-9]+.*>         # 匹配 <hr size=14 />


## 区间量词 : 规定重现次数的范围
...{min,max}                    # 某些版本的 egrep 可以自定义重现次数的区间
[a-zA-z]{1,5}                   # 英文字母,出现 1~5 次



# 括号及反向引用
(expression)...\1               # 匹配与表达式先前部分匹配的同样的文本, 括号可以记忆其中子表达式匹配的文本,而 \1 可以引用记住的内容
\<([A-Za-z]+).+\1\>             # 表示反向引用一次([A-Za-z]+) 的内容
([a-z])([0-9])\1\2              # \1 表示引用 ([a-z]) 中的内容,\2 表示引用 ([0-9]) 的内容


# 转义字符
$ egrep 'www.baidu.com' file    # 由于 ‘.’ 是元字符,所以无法匹配 www.baidu.com
$ 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值