正则表达式学习(一)

Published:

最近学习了正则表达式,在这里记录一下。个人认为正则这个东西主要还是多看多用,熟练工种。。。用多了自然就熟悉了……这篇文章主要记录了一些元字符的用法以及正则表达式的一些特性例如回溯引用、前后查找等等。

基本元字符

元字符 说明
. 匹配任意单个字符(任何非换行字符)
\ 对下一个字符转义
| 逻辑或操作符
[] 匹配字符集合中的某一个字符,[]不匹配任何字符,只负责定义一个字符集合。
(例如[abc]定义了一个包含a, b, c三个字母的字符集合)
[^] 对字符集合求非,(例如[^0-9]将匹配任何不是数字的字符。)
- 定义一个区间(例如[0-9])。
-是一个特殊的元字符,作为元字符只能用在[]之间。
在字符集合以外的地方,-只是一个普通字符,只能匹配-
因此,在正则表达式里,-不需要被转义。


数量元字符

元字符 说明
* 匹配前一个字符(子表达式)的零次或多次
*? *的懒惰型版本
+ 匹配前一个字符(子表达式)的一次或多次
+? +的懒惰型版本
? 匹配前一个字符(子表达式)的零次或一次
{n} 匹配前一个字符(子表达式)的n次重复
{m, n} 匹配前一个字符(子表达式)至少m次,至多n次重复
{n, } 匹配前一个字符(子表达式)n次或更多次重复
{n, }? {n, }的懒惰型版本

+*都是贪婪型元字符,在匹配时会尽可能的从一段文本的开头一直匹配到这段文本的末尾,而不是从这段文本的开头匹配到碰到第一个匹配时位置。

位置元字符

元字符 说明
^ 匹配字符串的开头。当它出现在一个字符集合里(被放在[]之间)并紧跟在左方括号[的后面时,
它才能发挥求非的作用。如果是在字符集合的外面并位于一个模式的开头,则它将匹配字符串的开头。
\A 匹配字符串的开头
$ 匹配字符串的结束
\Z 匹配字符串的结束
\< 匹配单词的开头
\> 匹配单词的结束
\b 匹配单词的边界(开头和结束)。它匹配的是这样一个位置,
这个位置位于一个能够用来构成单词的字符(字母,数字和下划线,也就是与\w相匹配的字符)
和一个不能用来构成单词的字符(也就是与\W相匹配的字符)之间。
\b匹配且只匹配一个位置,不匹配任何字符。用\bcat匹配到的字符串长度是3个字符(c, a, t),而不是5个字符。


\B \b的反义,表明不匹配一个单词边界,例如 \B-\B能够匹配border - color而不能匹配border-color

特殊字符元字符

元字符 说明
[\b] 匹配一个退格字符
\c 匹配一个控制字符
\d 匹配任意一个数字字符(等价于[0-9]
\D \d的反义,匹配一个非数字字符(等价于[^0-9]
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符
\s 匹配一个空白字符(等价于[\f\n\r\t\v]
\S \s的反义,匹配一个非空白字符(等价于[^\f\n\r\t\v]
\t 匹配一个制表符(Tab键)
\v 匹配一个垂直制表符
\w 匹配一个字母数字字符(大小写均可)或下划线(等价于[a-zA-Z0-9_]
\W \w的反义,匹配一个非字母数字下划线字符(等价于[^a-zA-Z0-9_]
\x 匹配一个十六进制数字
\0 匹配一个八进制数字

回溯引用和前后查找

元字符 说明
() 定义一个子表达式,子表达式是一个更大的表达式的一部分,
把一个表达式划分为一系列子表达式的目的是为了把那些子表达式当作一个独立元素使用。
分析子表达式时,应该按照先内后外的原则来进行。

\1 匹配第一个子表达式;\2匹配第二个子表达式,依此类推
?= 向前查找
?! 负向前查找
?<= 向后查找
?<! 负向后查找
?() 条件(if then)
?()| 条件(if then else)

回溯引用指模式的后半部分引用在模式的前半部分中定义的子表达式(可以把回溯引用想象成变量)。回溯引用只能用来引用模式里的子表达式(用()括起来的正则表达式片段) 如:[ ]+(\w+)[ ]+\1,这个正则表达式会匹配一段文本中连续重复出现的单词,其中[ ]+匹配一个或多个空格,\w+匹配一个或多个字母数字字符,[ ]+匹配随后的空格。注意,\w+是在括号里的,是一个子表达式,这个子表达式的作用是把整个模式的一部分单独划分出来以便在后面引用。这个模式的最后一部分是\1,这是一个回溯引用,它引用的就是前面划分出来的子表达式(\w+)\1代表的就是模式的第一个子表达式,同样,\2代表第二个,\3代表第三个……\0通常代表整个正则表达式。 js中用\来标识回溯引用,但是在替换操作时,用$代替\

前后查找是指包含的匹配本身并不返回,而是用于确定正确的匹配位置,它并不是匹配结果的一部分。前后查找分为向前查找和向后查找,js不支持向后查找

向前查找查找出现在被匹配文本之后(右边)的字符,但是不消费这个字符。向前查找指定了一个必须匹配但不在结果中返回的模式。向前查找实际上就是一个子表达式。语法上看,一个向前查找模式其实就是一个以?=开头的子表达式,需要匹配的文本跟在=后面。向前查找和向后查找本身其实是有返回结果的,只是这个结果的长度永远是0而已,因此,前后查找操作有时也被称为零宽查找。 向后查找查找出现在被匹配文本之前(左边)的字符,但是不消费它。向后查找操作符是?<=

大小写转换

元字符 说明
\E 结束\L\U转换
\l 把下一个字符(或子表达式)转为小写
\L 把后面的字符转为小写,直到遇到\E为止
\u 把下一个字符(或子表达式)转为大写
\U 把后面的字符转为大写,直到遇到\E为止

匹配模式

元字符 说明
(?m) 分行匹配模式

(?m) 使得正则表达式引擎把行分隔符当做一个字符串分隔符来处理。在分行模式下,^不仅匹配正常的字符串开头,还将匹配分隔符(换行符)后面的开始位置(这个位置不可见);类似的,$不仅匹配正常的字符串结尾,还将匹配分隔符(换行符)后面的结束位置。在使用的时候,(?m)必须出现在整个模式的最前面。(有些正则表达式不支持(?m))如下例子,利用正则表达式匹配出每行注释:

function test () {
    // this a comment
    alert(1);
    // this another comment
    alert(1);
}

^\s*//.*$将匹配一个字符串的开始,然后是多个空白字符,在后面是//,再往后是任意文本,最后是一个字符串的结束。不过,这个模式只能找到第一条注释(并认为这条注释将一直延续到文件结尾,因为*是一个贪婪型的元字符)。加上(?m)后,(?m)^\s*//.*$将把换行符视为一个字符串分隔符,这样就可以把每行注释都匹配出来。