如题所述
上一章分享了正式表达式的入门知识,以及单字符、多字符常用的匹配方法,对于工作维护过程中已经够用,但是有时候只使用基础知识来实现就会比较麻烦,如果使用高级用法就会比较方便很多。
例如:匹配一个HTML文件中两个 <B> 标签中的文件。
文本内容:
从上一章内容的知识可以想到的表达式可能如下:
但是这个表达式配置的结果是 AK</B> and <B>HI ,而不是我们想要的 AK 和 HI 。
实现很简单,就是在原有“贪婪型”元字符后面加上一个 ? 号,如下表格
前面的元字符都是对紧挨着前面的一个字符有效,例如表达式 the{3} 匹配 theee 字符串,假如我们想匹配连续三个 the 字符串怎么办呢,这就涉及到子表达式的概念。
把一个表达式匹配的内容做为一个单独的元素嵌入到另外一个表达式中,那这个做为独立元素的表达式就是子表达式,需要使用 () 括起来。这个跟数学的表达式概念很类似。
并且子表达与数学表达式还有一个类似的地方就是,正则表达式的子表达式也可以嵌套使用
假如我们再加个条件:我们想匹配连续三个 the 或者连续三个 you ,怎么实现?这就是正则表达式的选择操作符,也叫或操作符了
上面的问题就可以使用正则表达式 (the|you){3} 来表示
当一个模式的全部或者部分内容由 一对括号括起来 时,就对表达式进行了分组(其实就是放在 () 中的子表达式),并且把分组匹配到内容捕获并且临时存放在内存中。这就是捕获分组,可以在后面表达式中使用就叫后向引用,或者叫回溯引用。
默认情况下,分组是从左到右依次排序从1编号,第一个分组就是1,第二个分组就是2等等。
后向引用很简单就是一个 \ 或者 $ 后面跟相应编号即可。例如 \1 或者 $1 就表示引用第一个捕获分组。
前面讲捕获分组都是通过位置编号来访问,在perl和python、.NET等语言中还支持对捕获分组命名。这样就比较容易理解
顾名思义,与捕获分组相反,就是不会将分组匹配的内容放在内存中。主要是为了提高性能。
使用方法:在分组的开头加上 ?: ,例如 (?:the)
环视是一种非捕获分组,它根据某个模式之前或者之后的内容要求匹配其他模式。环视也称为零宽度断言。
(?(id/name)yes-pattern|no-pattern)
如果给定的 id 或 name 存在,将会尝试匹配 yes-pattern ;否则就尝试匹配 no-pattern , no-pattern 可选;
例如:email样式匹配 (<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) ,当 < 存在时,则最后要匹配 > ;否则匹配结束符 $
《学习正则表达式》
《正则表达式必知必会》