正则表达式(二)

正则的高级规则

元字符

元字符是在正则表达式中有特殊含义的字符。
如英文字符.
方括号 [ 也是,标志着一个字符集合的开始。
元字符在正则中有特殊的含义,这些字符不表示本身。
前面用到的 \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个数字。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值