美文网首页
读《精通正则表达式》

读《精通正则表达式》

作者: JLUiceman | 来源:发表于2019-03-06 23:10 被阅读0次

todo:提取要点,梳理结构图

第一章

1. ^脱字符

2. 正则表达式结构体(字符组)即=> [ ],只有在字符组内部且不是出现在头部,连字符(-)才是元字符,其他的元字符(脱字符除外)在字符组内部均为普通字符, 同时需要注意字符组只是匹配一个字符(和()多选结构区分开)

3. 排除型字符组表示的是"匹配一个未列出的字符"而非"不要匹配列出的字符",即是一种肯定断言,即使名字里包含了“排除”两个字,它仍然需要匹配一个字符

4. 一个字符组只能匹配目标文本中的单个字符,而每个多选结构自身都可能是完成的正则表达式,都可以匹配任意长度的文本

5. < 和 > 用于匹配单词的开头和结束位置(eg: <cat 匹配以cat开头的单词),<和>本身不是元字符,只有与反斜线结合时才是元字符(js不支持,可用\b元字符替代)

6. 可选项元素=> ? 与其他元字符不同,只作用于之前紧邻的元素or多选结构(即括号),表示此处容许出现或不出现这个字符

7.其他量词: + 表示之前紧邻的元素出现一次或多次; * 表示之前紧邻的元素出现任意多次获不出现;{ x, y} 表示之前紧邻的元素出现x-y之间的次数

8.反向引用: 允许匹配与表达式先前部分匹配的同样的文本(实测js实现的正则引擎不支持),用下划线+数字来表示(eg: ([a-z])(0-9)\1\2, \1表示[a-z]匹配的内容,\2表示[0-9]表示的内容)

9.转义符:\ 无需多言

10.常用的正则例子:

作用 正则
匹配变量名 [a-zA-Z_][a-zA-Z_0-9]*
引号内的字符串 "[^"]*"
金额 $[0-9]+(.[0-9][0-9])?

11. 我觉得挺有道理的一句话:字节如何解释只是视角(或称作编码更合适些)的问题


第二章 (入门示例拓展)

1.一些Perl的tip:

命令 含义
m/正则/ 对该正则进行匹配
=~ 连接正则表达式和待搜索的目标字符串

2. 用()来分组和捕获,用(?:)表示只分组不捕获·

3. 注意(x|y) 和[xy]*的区别

4. 字符组的子语言的规范不同于正则表达式主体,元字符的的定义在正则表达式中并不是统一的(eg: \b)

5. 一些元字符的简记法

元字符 含义
\t 制表符
\n 换行符、
\r 回车符
\s 任何空白字符
\S 任何非空白字符
\w [a-zA-Z0-9]
\W 除\w以外的字符
\d [0-9]
\D 非数字字符

6.Perl中使用1,2,$3....之类的变量来保存()分组匹配到的值,可以通过这种方法从字符串中提取信息

7.一种保留两位or三位小数(根据第三位是否非0)的正则表达式(Perl版本): s/(.\d\d[1-9]?)\d*/$1/

js版本: const reg = /(.\d\d[1-9]?)\d*/; const string = string.replace(reg, RegExp.$1)

8. "环视"结构不匹配任何字符,只匹配文本中的特定位置

顺序环视(从左往右): (?=正则)
逆序环视(从右往左): (?<=正则)
eg: 正则为: (?=Jeffrey)Jeff, 则Jeffrey可以匹配,Jeffrex不能匹配,尽管环视结构并不匹配任何字符

使用环视替换字符: Jeffs => Jeff's 则可以使用(perl语法)s/(?<=\bJeff)(?=s\b)/'/g(即找到这样一个位置: 紧接在Jeff之后,在s之前,将其替换为')

使用环视完成数字每三位插入一个逗号(16777272 => 16,777,272): s/(?<=\d) (?=(\d\d\d)+$)/,/g(即寻找这样的位置:左侧为数字,右侧为3的倍数个数字)

9. 其他环视

类型 正则表达式 匹配成功的条件
肯定逆序环视 (?<=.....) 子表达式能够匹配左侧文本
否定逆序环视 (?<!.....) 子表达式不能够匹配左侧文本
肯定逆序环视 (?<=.....) 子表达式能够匹配右侧文本
肯定逆序环视 (?<!.....) 子表达式不能够匹配右侧文本

用环视表示\b(单词分界符)=> (?<!\w)(?=\w)|(?<=\w)(?!\w)

第三章(正则表示的特性和流派概览)

1.正则表达式的起源: 20世纪40年代的两位神经学家(Warren MCCulloch & Walter Pitts) => 数学家(Stephen Kleene)在代数中正式描述为"正则集合"

2.正则相关的工具:

  • qed => ed(后发展为Unix中的ed编辑器)
  • ed的"g/Regular Expression/p"最终成为独立的工具grep
  • AT&T贝尔实验室的Alfred Aho写出了egrep

3.字符编码: 本质上是一种写明的共识,它规定了不同数值的字节应该如何解释,相同的字节用于不同的编码所代表的值可能不同

4.编码应该考虑的点

  • 程序能否识别这种编码
  • 程序如何决定采用哪种编码来处理这些数据
  • 正则表达式对这种编码的支持程度如何

5.正则表达式编码支持程度应该考虑的点

  • 是否能够支持多字节字符?eg: 点号(.)和[^x]之类的表达式是匹配单个字符还是单个字节?
  • \w,\d,\s之类的元字符 ,是否额能够识别编码中的所有字符?eg:é亦是字符,此时能否匹配
  • 程序是否会扩展对字符组的解释?eg: [a-z]能否匹配é
  • 不区分大小写的匹配是否对所有字符有效?eg:é

6.Unicode相关

  • 从基本的意义上说,Unicode是一组字符设定(或者是从数字和字符之间的逻辑映射的概念编码)(注意非编码)
    而将这种映射的概念编码为数据的方式有很多: UCS-2(所有字符都占用两个), UCS-4(所有字符占用4个字节),UTF-16(大部分字符占用两个字节,有一些字符占用4个字节),UTF-8(用1-6个字节来编码字符)
  • 支持Unicode的程序中的正则表达式通常支持\u{unicode数字num}元序列,用来匹配一个具体的unicode字符;eg:\uC05B匹配的是编号为U+C05B的Unicode字符,而非具体的字节,因为具体的字节是由代表这个Unicode代码点的编码方式在内部决定的
  • 一般人眼里的字符并不都会被Unicode或者支持Unicode的程序(正则引擎)看作一个字符,比如é看上去是一个字符,其实在Unicode中它可能有两个代码点构成(一个表示e,一个表示钝重音) =>带来问题:点号(.)是匹配单个代码点还是整个代码点组合
  • 实践中,大部分程序将"字符"和"代码点"视为等价,及匹配单个代码点
  • 理论上Unicode应该是代码点和字符之间的一一映射,实际上存在多种情况,例如à可以表示为U+0061加上U+0300,它也可以用单个代码点U+00E0表示(原因是为了保证Unicode和Latin-1之间转换的简易性)
  • Unicode Version 3.1增加了U+FFFF之后的代码点(比如代表音乐谱号C的字符对应代码点U+1D121)
  • Unicode中的行终止符(存在多种)=>影响文本行从文件读入的方式,影响正则的点号(.)及^,$和\Z的匹配
字符 Unicode码 描述
LF U+000A ASCII换行符
VT U+000B ASCII垂直制表符
FF U+000C ASCII进纸符
CR U+000D ASCII回车
CR/LF U+000A U+000D ASCII回车/换行
NEL U+0085 Unicode换行
LS U+2028 Unicode行分隔符
PS U+2029 Unicode段分隔符

7.正则模式和匹配模式

  • 不区分大小写的匹配模式(i): 问题=>1.存在特殊的与Unicode相关的问题,即并非所有的ASCII字母和数字字符都存在大小写形式,某些字符在大写和小写之间没有明显的一对一映射
  • 宽松排列和注释模式: 此模式忽略字符组外部的所有空白字符
  • 点号通配模式(dot-match-all match mode,也叫单行模式):通常点号(.)无法匹配换行符,而大部分现代编程语言则提供了两种方法供正则表达式选择
  • 增强的行锚点模式(Enhanced Line-anchor match mode,也叫"多行文本模式"):影响行锚点"^"和""的匹配,通常情况下锚点"^"不能匹配字符串内部的换行符,而只能匹配目标字符串的起始位置,但是在此模式下能够匹配字符串内嵌的文本行的开头位置.支持此模式的程序通常提供"\A"和"\Z"元字符,作用于普通的"^"和""一样,只是在此模式下它们的意义不会发生变化,永远不会匹配字串内部的换行符
  • 文本文字模式: 此模式几乎不能识别任何正则表达式元字符(eg: [a-z]* 的正则在此模式下匹配的是字符串"[a-z]*")
  • “多行模式”和"单行模式"的区别: 后者修改的是点号的匹配规则(换行符需要特殊处理=>不需要特殊处理),前者修改的是"^"和"$"的匹配规则(换行符不需要特殊处理=>需要特殊处理)

8.常见的元字符

  • 字符缩略表示法
元字符 含义 解释
\a 警报 对应ASCII中的<BEL>
\b 退格 对应ASCII中的<BS>,八进制编码010,在许多流派中\b只有在字符组内才表示退格,否则代表单词边界
\e Escape字符 通常对应ASCII中的<ESC>,八进制编码033
\f 进纸符 对应ASCII中的<FF>,八进制编码014
\n 换行符 macos平台中对应ASCII的<CR>,其他平台对应<LF>
\r 回车 对应ASCII中的<CR>,MacOs中对应ASCII的<LF>
\t 水平制表符 对应ASCII中的<HT>,八进制编码011
\v 垂直制表符 对应ASCII中的<VT>,八进制编码013

9.字符组及相关结构

  • 字符组通常表示肯定断言,即它必须匹配一个字符,排除型字符组仍然需要匹配一个字符,只是它没有在字符组中列出而已(注意[a-Z]和[a-zA-Z]的区别)
  • 点号能匹配除了换行符之外的任何字符(可以通过更改匹配模式切换)
  • Unicode属性,字母表和区块(p121,暂不记录)
  • .NET支持字符组减法(eg: [[a-z]-[aeiou]])

10.锚点及其他"零长度断言"(只匹配位置)

  • 脱字符"^"匹配需要搜索的文本的起始位置,若使用了增强的行锚点匹配模式,还能匹配每个换行符之后的位置

第4章

1.正则引擎的分类

  • DFA 确定有限自动机DFA
  • NFA 不确定有限自动机

相关文章

  • 正则表达式高级

    正则表达式高级——《精通正则表达式》+Java/Go/Python官方文档+多年经验+实验结果知识整理 [TOC]...

  • 读《精通正则表达式》

    todo:提取要点,梳理结构图 第一章 1. ^脱字符 2. 正则表达式结构体(字符组)即=> [ ],只有在字符...

  • 正则表达式(1)

    本博客来自精通正则表达式第三版 第一章:正则表达式入门(Introduction to regex) 正则表达式概...

  • 正则表达式优化

    正则表达式优化——《精通正则表达式》总结 [TOC] 第4章:表达式的匹配原理 引擎 DFA (Determini...

  • 粗通正则表达式

    前言 本文并非原创,内容分别摘自维基百科、《精通正则表达式》第三版、正则表达式30分钟入门教程。 什么是正则表达式...

  • 网页的解析之XPATH

    本文章属于爬虫入门到精通系统教程第六讲 在爬虫入门到精通第五讲中,我们了解了如何用正则表达式去抓取我们想要的内容....

  • 30分钟玩转「正则表达式」

    简介 推荐阅读:Jeffrey Friedl 《精通正则表达式(第3版)》,本文是该书的读书笔记。 本文「作业部落...

  • [精通正则表达式(第三版)]高清电子书PDF下载(适用JavaS

    [精通正则表达式(第三版)]高清电子书PDF下载 (适用JavaScript,Perl,PHP,Java,Pyth...

  • 书籍归档

    PHP入门到精通(朋友赠送) 正则表达式必知必会(朋友赠送) SQL必知必会(朋友赠送) Docker技术入门与实...

  • 正则表达式的高级用法——正|反向预查

    我之前一直自诩精通正则表达式(毕竟我实现过正则引擎),但关于正则表达式有几个特殊用法我一直都不熟,一来是用的少,二...

网友评论

      本文标题:读《精通正则表达式》

      本文链接:https://www.haomeiwen.com/subject/znmfpqtx.html