8.1 回溯引用有什么用?
- · - ·
为了理解回溯引用的概念,我们最好是看一个例子,前端程序员经常使用标题标签(<h1> 到 <h6>,以及配对的结束标签)来定义和排版网页里面的标题文字。
现在,我们不妨假设你需要把某个页面里的所有标题全部查找出来,而不管它的级别是多少。看下面的例子:
<h1>.*</h1>
<body>
<h1>玩转正则表达式教程</h1>
欢迎来到正则表达式教程
<h2>第一章 正则表达式入门</h2>
正则表达式入门
<h3>1.1 正则表达式的用途</h3>
正则表达式的用途
<h3>1.2 如何使用正则表达式</h3>
如何使用正则表达式
<h2>第二章 匹配单个字符</h2>
匹配单个字符
<h3>2.1 匹配普通文本</h3>
匹配普通文本
<h3>2.2 匹配任意字符</h3>
匹配任意字符
<h2>第三章 匹配一组字符</h2>
匹配一组字符
<h3>3.1 匹配多个字符中的某一个</h3>
匹配多个字符中的某一个
<h3>3.2 利用字符集合区间</h3>
利用字符集合区间
</body>
模式 <h1>.*</h1>
只能匹配一级标题,但我们说的是匹配任意级别的标题,这应该怎么办呢?最好的办法是用一个字符集合来代替 1,看下面的例子:
<h[1-6]>.*?</h[1-6]>
<body> <h1>玩转正则表达式教程</h1> 欢迎来到正则表达式教程 <h2>第一章 正则表达式入门</h2> 正则表达式入门 <h3>1.1 正则表达式的用途</h3> 正则表达式的用途 <h3>1.2 如何使用正则表达式</h3> 如何使用正则表达式 <h2>第二章 匹配单个字符</h2> 匹配单个字符 <h3>2.1 匹配普通文本</h3> 匹配普通文本 <h3>2.2 匹配任意字符</h3> 匹配任意字符 <h2>第三章 匹配一组字符</h2> 匹配一组字符 <h3>3.1 匹配多个字符中的某一个</h3> 匹配多个字符中的某一个 <h3>3.2 利用字符集合区间</h3> 利用字符集合区间 </body>
这个模式看起来不错,匹配任何一级标题的开始标签和结束标签。
注意
这里使用的是 .*?
(懒惰型)而不是 .*
(贪婪型)。我们在 第五章 里讲过, *
和其他几个元字符是“贪婪型”元字符,所以模式 <h[1-6]>.*?</h[1-6]>
有可能会从第 2 行的<h1>一直匹配到最后面的 </h2>,这可不是我们想要的结果;使用“懒惰型”元字符. *?
解决了这个问题。
之所以说“有可能”而不是“肯定”,是因为在这个特定的例子里即便是使用了“贪婪型”元字符也不一定会有问题。一般来说,元字符 .
不匹配换行符,而上例中的每个标题都各自占据一行。但在这里使用懒惰型元字符没有任何坏处——事前小心总比事后后悔好。
现在成功了吗?未必。来看看下面这个使用同一个模式的例子,你就知道了:
<h[1-6]>.*?</h[1-6]>
<body> <h1>玩转正则表达式教程</h1> 欢迎来到正则表达式教程 <h2>第一章 正则表达式入门</h2> 正则表达式入门 <h3>1.1 正则表达式的用途</h3> 正则表达式的用途 <h3>1.2 如何使用正则表达式</h3> 如何使用正则表达式 <h2>第二章 匹配单个字符</h2> 匹配单个字符 <h3>2.1 匹配普通文本</h3> 匹配普通文本 <h3>2.2 匹配任意字符</h3> 匹配任意字符 <h2>第三章 匹配一组字符</h2> 匹配一组字符 <h3>3.1 匹配多个字符中的某一个</h3> 匹配多个字符中的某一个 <h3>3.2 利用字符集合区间</h3> 利用字符集合区间 <h2>这是一个错误的标题</h3> </body>
在这个例子里,原始文本里有一个标题是以<h2>开头、以<h3>结束的。这显然是一个不合法的标题,但它与我们所使用的模式匹配上了。
出现这种情况的根源是这个模式的第 2 部分(用来匹配结束标签的那个部分)对这个模式的第 1 部分(用来匹配开始标签的那个部分)毫无所知。要想彻底解决这个问题,就只能求助于回溯引用。
该内容基于 《正则表达式必知必会》 二度创作
转载请遵守原作者相关协议并注明本页地址
https://iamhefang.cn/tutorials/正则表达式/第八章-回溯引用/8.1-回溯引用有什么用