读《精通正则表达式》

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 不确定有限自动机
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容

  • Python中的正则表达式(re) import rere.match #从开始位置开始匹配,如果开头没有则无re...
    BigJeffWang阅读 7,031评论 0 99
  • 初衷:看了很多视频、文章,最后却通通忘记了,别人的知识依旧是别人的,自己却什么都没获得。此系列文章旨在加深自己的印...
    DCbryant阅读 3,979评论 0 20
  • 个人根据《正则指引》内容总结记录,侵删!! 转载至我的博客 最近看了编译原理方面的书,觉得正则表达式非常重要,在各...
    J退後阅读 593评论 0 0
  • 正则表达式基础 元字符 正则表达式语言由两种基本字符类型组成: 原意文本字符 和 元字符 元字符使正则表达式具有处...
    滇西之王阅读 600评论 2 3
  • 01. 当我们拿花送给别人的时候,首先闻到花香的是自己;当我们抓起泥巴抛向别人的时候,首先弄脏的也是自己的手。 0...
    人生本是一场旅行阅读 462评论 0 0