PS:之前看《精通正则表达式》部分摘录,只是备忘,不适合阅读!Sorry!
#有一定的理论素养,却又始终以实践为本!
正则表达式能够得到众多语言和工具的支持是有原因的: 它们极其有用. 从较低的层面上来说,正则表达式描述的是一串文本( a chunk of text )的特征。我们可以用它来验证用户输入的数据,或者也可以用它来检索大量的文本。从较高的层面上来说,正则表达式容许用户掌控他们自己的数据——控制这些数据,让它们为自己服务。掌握正则表达式,就是掌握自己的数据。
正则表达式(Regular Expression )是强大、便捷、高效的文本处理工具。正则表达式本身,加上如同一门袖珍编程语言的通用模式表示法(general pattern notation ) ,赋予使用者描述
和分析文本的能力。配合上特定工具提供的额外支持,正则表达式能够添加、删除、分离、叠加、插入和修整各种类型的文本和数据。
一个字符组,即使是排除型字符组,也需要匹配一个字符。
如果我们需要在表达式中使用一个“匹配任何字符”的占位符(placeholder),用点号就很方便。
一个字符组只能匹配目标文件中的单个字符,而每个多选结构自身都可能是完整的正则表达式,都可以匹配任意长度的文本。
字符组基本可以算是一门独立的微型语言(例如,对与元字符,它们有自己的规定),而多选结构是“正则表达式语言主体“(main regular expression language) 的一部分。你将会发现,这两者都非常有用。
穷举所有可能出现的重复单词显然是不可能完成的任务。如果我们先匹配任意一个单词,接下来检查“后面的单词是否与它一样”,就好办多了。
反向引用是正则表达式的特性之一,它容许我们匹配与表达式先前部分匹配的同样的文本。
在支持反向引用的工具软件中,括号能够“记忆”其中的子表达式匹配的文本,不论这些文本是什么,元字符序列 【\1】能记住它们。
任何语言中都存在不同的方言和口音,很不辛,正则表达式也一样。情况似乎是,每一种支持正则表达式的语言都提供了自己的“改进”。
正则表达式的不断发展,但多年的变化也造就了数目众多的正则表达式“流派”( flavor)。
% perl -p -i -e 's/sysread/read/g' file.txt
这条命令中的 perl 程序是 s/sysread/read/g (是的,这就是一个完整的 perl 程序——参数 -e 表示整个程序接在命令的后面)。
参数 -p 表示对目标文件的每一行进行查找和替换,而 -i 表示将替换的结果写回到文件。
==========================================================
脱字符 ^ 匹配需要搜索的文本的起始位置,如果使用了增强 的行锚点匹配模式,它还能匹配每个换行符之后的位置。在某些系统中,增强模式下 ^ 还能匹配 Unicode 的行终结符.如果可以使用,无论在什么匹配模式下, \A 总是能匹配待搜索文本的起始位置。 (在 grep 中没有~验证了,高版本中不清楚)
===============================================================
正则引擎的分类
正则引擎主要可以分为基本不同的两大类:
一种是 DFA(确定的有穷自动机,相当于之前说的电动机),
另一种是 NFA (不确定的有穷自动机,相当于前面的汽油机)。
两条普适的原则:
1,优先选择最左端(最靠开头)的匹配结果。
2,标准的匹配量词(*, +, ? 和 {m, n} ) 是匹配优先的。
捕获括号(以及相应的反向引用和$1表示法)就像汽油添加剂一样——它们只对汽油机(NFA)起作用,对电动机 (DFA)不起作用。忽略优先量词也是如此。
匹配优先量词之所有得名,是因为它们总是(或者,至少是尝试)匹配多于匹配成功下限的字符。
标准量词的匹配优先中的,"过度的匹配优先以及先来先服务等的分析!" P152
表达式主导与文本主导
DFA 和 NFA 反映了将正则表达式在应用算法上的根本差异。作者把对应汽油机的 NFA 称为 “表达式主导 (regex-directed) " 引擎,而对应电动机的 DFA 称为 "文本主导 (text-directed) “ 引擎。
表达式中的控制权在不同的元素之间转换,所以作者称它为“表达式主导”。
与表达式主导的NFA不同,DFA引擎在扫描字符串时,会记录“当前有效”的所有匹配可能。
称这种方式为“文本主导”,是因为它扫描的字符串中的每个字符都对引擎进行了控制。
很多不同的表达式都可以捕获相同的结果,但是它们以不同的方式控制引擎。
DFA并不关心表达式的形式!
关于NFA中回溯的一条重要原则:如果需要在“进行尝试”和“跳过尝试“之间选择,对于匹配优先量词,引擎会优先选择“进行尝试”,而对于忽略优先量词,会选择“跳过尝试“。
距离当前最近存储的选项就是当本地失败强制回溯时返回的。使用的原则是LIFO(last in first out, 后进先出)。
ab?c --> ? 是优先匹配的!
ab??c --> ??是忽略优先的!
注意一点:由星号(或其他任何匹配优先量词)限定的部分不受后面元素影响,而只是匹配尽可能多的内容。在之前例子中, . * 点星号,在点号匹配失败之前,完全不知道,到底应该在哪个数字或者是其他什么地方停下来。在 .*([0-9]+) 的例子中我们看到, [0-9]+ 只能匹配一位数字。
DFA不支持忽略优先!
.* 匹配时只从自身出发,匹配尽可能多的内容,只有在全局匹配需要的情况下才会“被迫”交还一些字符。有些时候问题很严重。