读《学习正则表达式》(1)

读《学习正则表达式》

准备

pcregrep

pcregrep是带有PCRE库的grep版本

Mac下安装pcregrep

brew install pcre
brew link pcre

第1章 什么是正则表达式

”正则表达式是描述一组字符串特征的模式,用来匹配特定的字符串。“ ------Ken Thompson

1.1 几个网址

这几个网址可以在线测试正则表达式

这是作者的github上关于本书的相关代码

https://github.com/michaeljamesfitzgerald/Introducing-Regular-Expressions

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章 简单的模式匹配

正则表达式的用途就是在文本中匹配和寻找模式。

匹配模式的简单方法:

  • 字符串字面值
  • 数字
  • 字母
  • 任意字符

在线正则表达式验证工具

https://regexr.com/

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模式

正则表达式的multiline和dotall模式

# 如果regexp里出现了^或者$, 那么by default只会匹配第一行. 设置了Multiline,会匹配所有行.
# 默认情况下, .不会匹配换行符, 设置了Dotall模式, .会匹配所有字符包括换行符

2.8 给文本加标签

# 给 The Rime of the Ancient Mariner 加标签

输入图片说明

用sed为文本加标签

输入图片说明

sed -n 's#^#<h1>#;s#$#</h1>#p;q' rime.txt

# 说明
三个命令,以;分隔
s#^#<h1># 表示行首加<h1>
s#$#</h1># 表示行尾加</h1>
q 表示结束sed程序,这样就只会处理一行
p 表示打印受影响的那一行

用sed的其他方式

# 使用e
sed -ne 's#^#<h1>#' -e 's#$#</h1>#p' -e 'q'

# 命令写入文件中
---h1.sed start---
#!/usr/bin/sed
s#^#<h1>#
s#$#</h1>#
q
---h1.sed end---
sed -fh1.sed rime.txt

用Perl为文本加标签

# 确认已经安装perl
perl -v

# 为第一行加标签
perl -ne 'if($. == 1){s#^#<h1>#;s#$#</h1>#m;print;}' rime.txt

# 说明
-n选项 输出全部输入内容
-e选项 允许在命令行中提交程序代码
if($. == 1) 检查是否在第一行,$.匹配当前行
m修饰符 多行修改符

写成perl脚本

---h1.pl start---
#!/usr/bin/perl -n
if ($. == 1) {
  s#^#<h1>#;
  s#$#</h1>#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 cold
Country towards the South Pole; and how from thence she made her course
to the tropical Latitude of the Great Pacific Ocean; and of the strange
things that befell; and in what manner the Ancyent Marinere came back to
his 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 eye
4        "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.txt
grep -Eoc '\<THE|The|the\>' rime.txt
grep -Eoc '\bTHE|The|the\b' rime.txt

# 说明
-E选项表示使用扩展的正则表达式
-o选项表示只输出与模式匹配的那部分
-c选项表示只返回结果的数量

3.3 其他锚位符

# 匹配单词the出现在行首附近位置且之前有一个或多个空格的次数
pcregrep -c '\A\s*(THE|The|the)' rime.txt

# 说明
\A匹配主题词的起始
\Z匹配主题词的结尾
\s匹配空格
-c选项表示返回匹配次数

# 匹配主题词尾部的MARINERE或Marinere
pcregrep -n '(MARINERE|Marinere)(.)?\Z' rime.txt

# 说明
-n选项输出行号

3.4 使用元字符的字面值

# 15个元字符
.^$*+?|(){}[]\-

# 匹配$
\Q$\E
\$

# 说明
\Q\E之间的任意字符都会被解释为普通字符

第4章 选择、分组和向后引用

分组可以帮助执行某种操作:

  • 在两种或更多可选模式中选择一个
  • 创建子模式
  • 捕获一个分组以便之后进行后向引用
  • 对组合的模式使用某项操作,如量词
  • 使用非捕获分组
  • 原子分组

4.1 选择操作

(THE|The|the)

# 使用选项
(?i)the

正则表达式中的选项

参考http://pcre.org/pcre.txt 中的NAMED SUBPATTERNS(命名子模式)

?d		Unix中的行
?i		不区分大小写
?J		允许重复的名字
?m		多行
?s		单行(dotall)
?u		Unicode
?U		默认最短匹配
?x		忽略空格和注释
?-...	复原或关闭选项

使用grep统计the出现的次数

grep -Ec "(THE|The|the)" rime.txt
grep -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修改符表示要打印该行

命名分组

命名分组		引用分组
(?<one>It is)	$+{one}或\kone或?P=one

4.3 非捕获分组

(?:THE|The|the)
(?i)(?:THE|The|the)
(?:(?i)the)
(?i:the)  推荐这样写

原子分组

如果使用的正则表达式引擎进行回溯操作,这种分组就可以将回溯操作关闭,但它只原子分组内的部分,而不是针对整个正则表达式。语法如下:

(?>the)

https://github.com/google/re2 非回溯引擎可彻底关闭回溯操作,而使用原子分组可以关闭正则表达式的部分回溯操作

第5章 字符组

字符组有时也被称为方括号表达式。

测试文本

https://github.com/michaeljamesfitzgerald/Introducing-Regular-Expressions/blob/master/ascii-graphic.txt

! " # $ % & ' () * + , - . /
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字符组

转载于:https://my.oschina.net/yysue/blog/1621432

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值