Regular|Regular Expression -- 正则表达式

摘要

正则表达式是一项优秀的技术,更是一门伟大的科学。这篇博客我将大概介绍一下它的历史,详细的讨 论一下它的语法,最后说一下它在 JavaScript 与 Linux 中的应用。 快速阅读步骤:定义 --> PATTERN --> JavaScript 中的 RegExp / Linux 中的 grep 命令

关键字 Regular Expression | Perl | JavaScript | Linux
故事 20世纪40年代:正则表达式最初的想法来自两位神经学家:沃尔特·皮茨与麦卡洛克,他们研究出了一种用数学方式来描述神经网络的模型。
1956年:一位名叫Stephen Kleene的数学科学家发表了一篇题目是《神经网事件的表示法》的论文,利用称之为正则集合的数学符号来描述此模型,引入了正则表达式的概念。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“正则表达式”这个术语。
1968年:C语言之父、UNIX之父肯·汤普森把这个“正则表达式”的理论成果用于做一些搜索算法的研究,他描述了一种正则表达式的编译器,于是出现了应该算是最早的正则表达式的编译器qed(这也就成为后来的grep编辑器)。
Unix使用正则之后,正则表达式不断的发展壮大,然后大规模应用于各种领域,根据这些领域各自的条件需要,又发展出了许多版本的正则表达式,出现了许多的分支。我们把这些分支叫做“流派”。
1987年:Perl语言诞生了,它综合了其他的语言,用正则表达式作为基础,开创了一个新的流派,Perl流派。之后很多编程语言如:Python、Java、Ruby、.Net、PHP等等在设计正则式支持的时候都参考Perl正则表达式。
定义与原理 定义 正则表达式是由一类特殊字符及文本字符所编写的模式,其中有些字符不表示其字面意义,而是用于表示控制或通配的功能。
原理 -- 正则表达式引擎
Regular Expression engine
这里可以参考猪哥的 这篇博客
PATTERN
一个 正则表达式通常被称为一个 模式,为( 第二声)用来 描述或匹配一系列匹配某个 句法规则的 字符串。
元字符
正则表达式由两种基本字符类型组成: 原义文本字符和 元字符。元字符使正则表达式具有处理能力。所谓元字符就是指那些在正则表达式中具有 特殊意义的专用字符,可以用来 规定其前导字符(即位于元字符前面的字符)在目标对象中的 出现模式。
字符匹配
.:匹配任意单个字符; []:匹配指定范围内的任意单个字符; [^] :匹配指定范围外的任意单个字符;

匹配次数
用在要指定其出现的次数的字符的后面,用于限制其前面字符出现的次数。
*:匹配其前面的字符任意次(0次、1次或多次); .*:匹配任意长度的任意字符; ?:匹配其前面的字符0次或1次,即其前面的字符可有可无; +:匹配其前面的字符1次或多次,即前面的字符至少要出现1次; {m}:匹配其前面的字符 m 次; {m,n}:匹配其前面的字符至少 m 次,至多 n 次; {0,n}:匹配其前面的字符至多 n 次; {m,} :匹配其前面的字符至少 m 次;

位置锚定
^:行首锚定,用于模式的最左侧; $:行尾锚定,用于模式的最右侧; ^PATTERN$:用 PATTERN 来匹配整行; ^$:匹配空白行; ^[[:space:]]*$:匹配空行或包含空白字符的行; 单词:非特殊字符组成的连续字符或字符串都称为单词; \< 或 \b:词首锚定,用于单词模式的左侧; \> 或 \b:词尾锚定,用于单词模式的右侧; \:匹配完整单词;

分组及引用
():将一个或多个字符捆绑在一起,当作一个整体进行处理; \1:模式从左侧起,第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符; \2:模式从左侧起,第二个左括号以及与之匹配的右括号之间的模式所匹配到的字符; 后向引用:引用前面的分组括号中的模式所匹配到的字符;

特殊元字符
\b :匹配一个词的边界; \d :匹配一个数字,等价于 [0-9]; \D :匹配一个非数字,等价于 [^0-9]; \n :匹配一个换行符; \r :匹配一个回车符; \s :匹配一个空白字符; \t :匹配一个制表符; \w :匹配一个单字字符,等价于 [A-Za-z0-9];

JavaScript 中的 RegExp
ECMAScript 通过 RegExp 类型来支持正则表达式;
定义方式
JavaScript 有两种定义正则表达式的方式。
字面量形式
var expression = / pattern / flags ;
其中的 pattern 就不再赘述,说一说 flags 标志位: g :global,全局模式,会匹配所有的字符串; i :case-insensitive,忽略大小写; m :multiline,多行模式,到达一行末尾时还会继续查找下一行;

RegExp 构造函数
var expression = new RegExp("pattern", "flags") ;
注意:传递给 RegExp 构造函数的两个参数都是字符串;

RegExp 实例属性
var pattern1 = /\[bc\]at/i; alert(pattern1.global); alert(pattern1.ignorecase); alert(pattern1.multiline); alert(pattern1.lastIndex); alert(pattern1.source); var pattern2 = new RegExp("\\[bc\\]at", "i"); alert(pattern1.global); alert(pattern1.ignorecase); alert(pattern1.multiline); alert(pattern1.lastIndex); alert(pattern1.source);

RegExp 实例方法 exec()
该方法接收一个 要应用模式的字符串作为参数,然后返回 包含第一个匹配项信息的数组。
var text = "mom and dad and baby"; var pattern1 =/mom ( and dad ( and baby)?)?/gi; var matches = pattern1.exec(text); // ["mom ", undefined, undefined, index: 0, input: "mom and dad and baby", groups: undefined] alert(matches.index) alert(matches.input) alert(matches[0]) alert(matches[1]) alert(matches[2])

【Regular|Regular Expression -- 正则表达式】对于 exec() 方法而言,即使在模式中设置了全局标志,它每次也只会返回一个匹配项。
test()
该方法接收一个 字符串参数,在模式与该参数匹配的情况下返回 true,否则返回 false。
var text = "000-00-0000"; var pattern = /\d{3}-\d{2}-\d{4}/; if (pattern.test(text)) { alert("The pattern was matched.") }

RegExp 构造函数属性
RegExp 的静态属性,这些属性 适用于作用域中的所有正则表达式,并且 基于所执行的最近一次正则表达式操作而变化。
input$_:最近一次要匹配的字符串; lastMatch$&:最近一次的匹配项; lastParen$+:最近一次匹配的捕获组; leftContext$`:input 字符串中 lastMatch 之前的文本; multiline$*:布尔值,表示是否所有表达式都使用多行模式; rightContext $':input 字符串中 lastMatch 之后的文本;

var text = "this has been a short summer"; var pattern = /(.)hort/g; if (pattern.test(text)) { alert(RegExp.input); // this has been a short summer alert(RegExp.leftContext); // this has been a alert(RegExp.rightContext); // summer alert(RegExp.lastMatch); // short alert(RegExp.lastParen); // s alert(RegExp.multiline); // false }

Linux 中的 grep 命令
Global search Regular Expression and Print out the line.
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]OPTIONS: --color=auto -i:忽略大小写; -o:仅显示匹配到的字符串本身; -v:显示不被模式匹配到的行; -E:支持使用扩展的正则表达式元字符; -q:静默模式; -A # :后 # 行; -B # :前 # 行; -C # :前后 # 行;

鸣谢
  • 维基百科
  • 百度百科
  • Linux 大师 马哥
  • 红宝书
  • 猪哥

    推荐阅读