读《学习正则表达式》
准备
pcregrep
pcregrep是带有PCRE库的grep版本
Mac下安装pcregrep
brew install pcrebrew link pcre
第1章 什么是正则表达式
”正则表达式是描述一组字符串特征的模式,用来匹配特定的字符串。“ ------Ken Thompson
1.1 几个网址
这几个网址可以在线测试正则表达式
- 第1章用到
- 第2章用到
这是作者的github上关于本书的相关代码
1.2 匹配北美的电话号码
北美的电话号码长这样:
707-827-7019
827.7079
(707)-827-7079
用字符串字面值来匹配:
用字符组来匹配数字:
[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]
使用字符组简写式:
# \d表示数字字符\d\d\d-\d\d\d-\d\d\d\d# 连字符 \D表示非数字字符\d\d\d\D\d\d\d\D\d\d\d\d
匹配任意字符
# 点号(.)是一个通配符,可以匹配任意字符,但不匹配换行符\d\d\d.\d\d\d.\d\d\d\d
捕获分组和向后引用
# 匹配区号707(\d)\d\1# 说明(\d)匹配第一个数字7并将其捕获,括号表示捕获\d匹配第二个数字0但没有捕获\1对捕获的数字进行反向引用,表示第一个捕获,即数字7
使用量词
\d{3}-?\d{3}-?\d{4}(\d{3,4}[.-]?)+(\d{3}[.-]?){2}\d{4}# 说明{3}表示前面的匹配出现3次+表示出现一个或多个*表示0个或多个?表示0个或1个
括选文字符
# 区号可以有也可以没有,可以带括号也可以不带括号^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$# 说明|表示选择^表示行首$表示行尾\(表示转义,即真正的左括号
1.3 编辑器
TextMate
Mac上的文本编辑器,采用与Ruby语言相同的正则表达式程序库
Notepad++
Windows上的编辑器,采用PCRE(Perl Compatible Regular Expression,Perl兼容正则表达式)库
Oxygen
XML编辑器,使用perl 5的正则表达式语法
第2章 简单的模式匹配
正则表达式的用途就是在文本中匹配和寻找模式。
匹配模式的简单方法:
- 字符串字面值
- 数字
- 字母
- 任意字符
在线正则表达式验证工具
2.1 匹配字符串字面值:
Ship
2.2 匹配数字
\d[0-9][0123456789][01]
2.3 匹配非数字字符
\D[^0-9][^\d]
2.4 匹配单词和非单词字符
# 匹配单词\w# 匹配非单词\W# 说明\w与\D的区别:\D会匹配空格、标点符号等字符\w:[_a-zA-Z0-9]
字符简写式
\a 报警符[\b] 退格字符 \c x 控制字符\d 数字字符\D 非数字字符\o xxx 字符的八进制值\w 单词字符\W 非单词字符\0 空字符\x xx 字符的十六进制值\u xxx 字符的Unicode值
2.5 匹配空白符
# 匹配空白符\s# 匹配非空白符\S# 说明\s与[\t\n\r]相同
匹配各种空白符的简写式
\f 换页符\h 水平空白符\H 非水平空白符\n 换行符\r 回车符\s 空白符\S 非空白符\t 水平制表符\v 垂直制表符\V 非垂直制表符
2.6 匹配任意字符
\bA.{5}T\b.*# 说明\b匹配单词的边界.*与[^\n]相同
2.7 multiline与dotall模式
# 如果regexp里出现了^或者$, 那么by default只会匹配第一行. 设置了Multiline,会匹配所有行.# 默认情况下, .不会匹配换行符, 设置了Dotall模式, .会匹配所有字符包括换行符
2.8 给文本加标签
# 给 The Rime of the Ancient Mariner 加标签
用sed为文本加标签
sed -n 's#^##;s#$#
#p;q' rime.txt# 说明三个命令,以;分隔s#^## 表示行首加
s#$#
# 表示行尾加q 表示结束sed程序,这样就只会处理一行p 表示打印受影响的那一行
用sed的其他方式
# 使用esed -ne 's#^##' -e 's#$#
#p' -e 'q'# 命令写入文件中---h1.sed start---#!/usr/bin/seds#^##s#$#
#q---h1.sed end---sed -fh1.sed rime.txt
用Perl为文本加标签
# 确认已经安装perlperl -v# 为第一行加标签perl -ne 'if($. == 1){s#^##;s#$#
#m;print;}' rime.txt# 说明-n选项 输出全部输入内容-e选项 允许在命令行中提交程序代码if($. == 1) 检查是否在第一行,$.匹配当前行m修饰符 多行修改符
写成perl脚本
---h1.pl start---#!/usr/bin/perl -nif ($. == 1) { s#^##; s#$#
#m; print;}---h1.pl end---# 执行perl h1.pl prime.txt
第3章 边界
断言标记边界,但是并不耗用字符。也就是说,字符并不会返回到结果中。断言也被称做零宽断言(zero-width assertion)。零宽断言不匹配字符,而是匹配字符串的中的位置。^和$也叫做锚位符(anchor)。
边界有以下几种:
- 行或者字符串的起始与结束位置
- 单词边界
- 主题词的起始与结束位置
- 引用字符串字面值的边界
测试网址
-
用这个
测试文本
THE RIME OF THE ANCYENT MARINERE, IN SEVEN PARTS.ARGUMENT.How a Ship having passed the Line was driven by Storms to the coldCountry towards the South Pole; and how from thence she made her courseto the tropical Latitude of the Great Pacific Ocean; and of the strangethings that befell; and in what manner the Ancyent Marinere came back tohis own Country.I.1 It is an ancyent Marinere,2 And he stoppeth one of three:3 "By thy long grey beard and thy glittering eye4 "Now wherefore stoppest me?
3.1 行的起始与结束
# 在multiline与dotall模式下,匹配How这一整段^How.*Country\.$# dotall模式下,匹配整个文本,因为.匹配包括换行符的所有字符THE.*\?$
3.2 单词边界与非单词边界
# gloal模式下,匹配第一行的两个THE\bTHE\b\Be\B# 说明\b是个零宽度断言,表面上它会匹配空格或者是行起始,而实际上它匹配的是个零宽度的不存在的东西。\b匹配单词边界\B匹配非单词边界\ <匹配单词开头,vim和grep中可用\> 匹配单词结尾grep -Eoc 'THE|The|the' rime.txtgrep -Eoc '\' rime.txtgrep -Eoc '\bTHE|The|the\b' rime.txt# 说明-E选项表示使用扩展的正则表达式-o选项表示只输出与模式匹配的那部分-c选项表示只返回结果的数量 匹配单词开头,vim和grep中可用\>
3.3 其他锚位符
# 匹配单词the出现在行首附近位置且之前有一个或多个空格的次数pcregrep -c '\A\s*(THE|The|the)' rime.txt# 说明\A匹配主题词的起始\Z匹配主题词的结尾\s匹配空格-c选项表示返回匹配次数# 匹配主题词尾部的MARINERE或Marinerepcregrep -n '(MARINERE|Marinere)(.)?\Z' rime.txt# 说明-n选项输出行号
3.4 使用元字符的字面值
# 15个元字符.^$*+?|(){}[]\-# 匹配$\Q$\E\$# 说明\Q\E之间的任意字符都会被解释为普通字符
第4章 选择、分组和向后引用
分组可以帮助执行某种操作:
- 在两种或更多可选模式中选择一个
- 创建子模式
- 捕获一个分组以便之后进行后向引用
- 对组合的模式使用某项操作,如量词
- 使用非捕获分组
- 原子分组
4.1 选择操作
(THE|The|the)# 使用选项(?i)the
正则表达式中的选项
参考 中的NAMED SUBPATTERNS(命名子模式)
?d Unix中的行?i 不区分大小写?J 允许重复的名字?m 多行?s 单行(dotall)?u Unicode?U 默认最短匹配?x 忽略空格和注释?-... 复原或关闭选项
使用grep统计the出现的次数
grep -Ec "(THE|The|the)" rime.txtgrep -Eo "(THE|The|the)" rime.txt | wc -l# 说明-E选项表示使用扩展的正则表达式(ERE),而不用基本的正则表达式(BRE)-c选项表示返回匹配的行数(不是匹配的单词)wc命令是单词计数命令-l选项是对输入的行数进行统计
4.2 子模式
(the|The|THE)(t|T)h(e|eir)\b[tT]h[ceinry]*\b
4.3 捕获分组和向后引用
# 向后引用\1或$1 引用第一个捕获的分组sed只能接受\1这种形式Perl则两种都接受
RegExr
sed
# 说明-E选项调用ERE(扩展的正则表达式),括号可以直接当成字面值来使用-n选项覆盖打印每一行的默认设置p修改符表示要打印该行
命名分组
命名分组 引用分组(?It is) $+{one}或\kone或?P=one
4.3 非捕获分组
(?:THE|The|the)(?i)(?:THE|The|the)(?:(?i)the)(?i:the) 推荐这样写
原子分组
如果使用的正则表达式引擎进行回溯操作,这种分组就可以将回溯操作关闭,但它只原子分组内的部分,而不是针对整个正则表达式。语法如下:
(?>the)
非回溯引擎可彻底关闭回溯操作,而使用原子分组可以关闭正则表达式的部分回溯操作
第5章 字符组
字符组有时也被称为方括号表达式。
测试文本
! " # $ % & ' () * + , - . /0 1 2 3 4 5 6 7 8 9: ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z[ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z{ | } ~
字符组匹配
# 元音[aeiou][a-z][a-f][0-9][3-6]# 10~19的偶数\b[1][24680]\b# 0~99的偶数\b[24680]\b|\b[1-9][24680]\b# 十六进制数[a-fA-F0-9]
5.1 字符组取反
# 不匹配元音字符[^aeiou]
5.2 并集与差集
Reggy,Mac桌面应用程序
# 并集[0-3[6-9]]# 差集[a-z&&[^m-r]]
5.3 POSIX字符组
POSIX(Portable Operating System Interface,可移植操作系统接口)是IEEE维护的一系列标准。其中包含了一个正则表达式标准(ISO/IEC/IEEE 9945:2009),该标准提供了一套命名的字符组,其形式为:
[[:xxxx:]]
xxxx是名字,如digit或word或alnum
# 对POSIX字符组取反[[:^xxxx:]]
5.4 本章所学
- 如何使用方括号表达式创建字符组或字符集
- 如何在字符组中创建一个或多个范围
- 如何匹配0到99范围内的偶数
- 如何匹配十六进制数
- 如何在字符组中使用简写式
- 如何对一个字符组进行取反
- 如何得到字符组的并集和差集
- 什么是POSIX字符组