正则的高级规则
元字符
元字符是在正则表达式中有特殊含义的字符。
如英文字符.
方括号 [ 也是,标志着一个字符集合的开始。
元字符在正则中有特殊的含义,这些字符不表示本身。
前面用到的 \b \f \n 都是元字符
具体可以自己看 ,例如
空白元字符 (\b \f \n)
数字元字符 (\d \D)
贪婪与非贪婪
贪婪模式
修饰匹配次数的时候,刚才介绍到了如{m,n} ? * +这些,
具体的匹配次数随被匹配的字符串定。
这种总是重复匹配不定次数,总是尽可能多的匹配。
对于字符串dxxxdxxxd
d\w+
匹配第一个d以及后的所有字符
d\wd
匹配第一个d和最后一个d之间的所有字符~
可以看到我们是尽可能多地匹配,
带?的表达式在可匹配可不匹配的时候也可能的”要匹配”。 这种匹配就是”贪婪”模式
非贪婪模式
在修饰匹配次数的特殊符号上再加上一个?号,
则可以使匹配次数不定的表达式尽可能少的匹配,
使可匹配可不匹配的表达式,尽量不可匹配。
还是对于字符串dxxxdxxxd
(d)(\w+?)
将尽可能少的匹配第一个”d”之后的字符
匹配结果是: dx
(d)(\w+?)(d)
匹配结果是:dxxxd
为了使整个表达式匹配成功,\w+? 不得不匹配xxx才可以让后面的d匹配。
举例1:
表达式 "<td>(.*)</td>"
与字符串"<td><p>aa</p></td> <td><p>bb</p></td>"
匹配时,匹配的结果是:成功;匹配到的内容是
"<td><p>aa</p></td> <td><p>bb</p></td>"
整个字符串, 表达式中的"</td>"
将与字符串中最后一个"</td>"
匹配。
举例2:
相比之下,表达式
"<td>(.*?)</td>"
匹配举例1中同样的字符串时,将只得到
"<td><p>aa</p></td>"
```
再次匹配下一个时,可以得到第二个
```
"<td><p>bb</p></td>"。
子表达式
什么是子表达式?
子表达式是一个更大的表达式的一部分;
如 (&npsp;)
为什么用子表达式
把一个表达式划分为一系列的子表达式的目的是为了把那些
子表达式当作一个独立元素来使用。
子表达式必须用()括起来
例如 用正则匹配IP地址
12.155.23.200
因为每组数字是由1个、2个或3个数字构成,这4组数字可以由 \d{1,3} 来匹配
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
显然这么做违反了DRY原则
我们使用子表达式:
(\d{1,3}\.){3}\d{1,3}
这个模式就可以匹配IP地址,而且不会重复自己。
反向引用
表达式在匹配时,表达式引擎会将小括号()包含的表达式所匹配到的字符串记录下来。
获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。
这一点在前面已经多次展示过了。
在实际场合中,当用某种边界查找,而要获取的内容又不包含边界时,
必须使用小括号来指定要的范围。 比如前面的”(.*?)”
其实”小括号包含的表达式所匹配到的字符串”不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。 表达式后边的部分,可以引用前面”括号内的子匹配已经匹配到的字符串“。
引用
\ 加上一个数字, “\1”表示引用第1对括号内匹配到的字符串,”\2”则为第2对,以此类推。
如果一对括号内包含另一对括号,则外层的括号先排序号。
例子
"('|")(.*?)(\1)"
匹配
” ‘Hello’, “World” ”
匹配到的内容是:” ‘Hello’ “。
再次匹配下一个时,可以匹配到 ” “World” “。
(\w)\1{4,}
匹配”aa bbbb abcdefg ccccc 111121111 999999999”时,匹配结果是:”cccccc”
再次匹配下一个的时候,得到999999999
它要求\w范围的字符至少重复5次,注意与/w{5,} 的区别
预搜索
^ $ /b 本身不匹配任何字符,只是对字符串两头或者字符之间的缝隙附加了条件。
正向预搜索
(?=xxxxx)
(?!xxxxx)
(?=xxxxx)在匹配的字符串中,它对所处的”缝隙”或”两头”附加的条件是:所在缝隙的右侧,必须能够匹配上xxxxx这部分的表达式。 因为它只是在此作为这个缝隙上附加的条件,它不影响后边的表达式去真正匹配这个缝隙之后的字符。 这就类似”/b”,本身不匹配任何字符。
Windows (?=NT|XP)
匹配”Windows 98, Windows NT, Windows 2000” 时,将只匹配”Window NT”中的 “Windows”,其他的Windows字样不匹配!
(\w)((?=\1\1\1)(\1))+
在匹配字符串”aaa ffffff 99999999” 时,将可以匹配6个f的前4个, 匹配9个”9”的前7个。
这个表达式的意思: 重复4次以上的字母数字,则匹配其剩下最后2位之前的部分。 当然这个表达式可以不这样写。
格式(?!xxxxx)
则相反,是所在缝隙的右侧,必须**不能匹配**xxxxx这部分表达式
((?!\bstop\b).)+
在匹配“fdjka ljfdl stop fjdsla fdj” 的时候,将从头一直匹配到”stop”之前的位置,如果字符串中没有”stop” 就匹配整个字符串。
do(?!\w)
匹配”done,do,dog” 只能匹配”do” . 因为是不能匹配所有的\w!
反向预搜索
(?<=xxxxxx)
(?
(?<=\d{4}\d+(?=\d{4}))
匹配123456780123456时,将匹配除了前4个数字和后4个数字之外的中间8个数字。