正则表达式高级技巧背后的关键概念[SM]

论坛 期权论坛     
选择匿名的用户   2021-5-30 01:44   347   0
<div class="blogpost-body" id="cnblogs_post_body">
<p>正则表达式(Regular Expression, <em>abbr. regex</em>) 功能强大,能够用于在一大串字符里找到所需信息。它利用约定俗成的字符结构表达式来发生作用。不幸的是,简单的正则表达式对于一些高级运用,功能远远不够。若要进行筛选的结构比较复杂,你可能就需要用到<strong>高级正则表达式</strong>。</p>
<p>本文为您<strong>介绍正则表达式的高级技巧</strong>。我们筛选出了八个常用的概念,并配上实例解析,每个例子都是满足某种复杂要求的简单写法。如果你对正则的基本概念尚缺乏了解,请先阅读<a href="http://unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#introduction" title="正则表达式入门">这篇文章</a>,或者<a href="http://www.regexlab.com/zh/deelx/syntax.htm">这个教程</a>,或者<a href="http://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F" title="维基百科">维基条目</a>。</p>
<p>这里的正则语法适用于PHP,与<a href="http://zh.wikipedia.org/wiki/Perl" title="维基百科">Perl</a>兼容。</p>
<p> </p>
<h3>1. 贪婪/懒惰</h3>
<p><img alt="Greed" height="300" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-551ad3214058193ffdf490a5708628db.jpg" width="400"></p>
<p>所有能多次限定的正则运算符都是贪婪的。他们<strong>尽可能多</strong>地匹配目标字符串,也就是说匹配结果会<strong>尽可能地长</strong>。不幸的是,这种做法并不总是我们想要的。因此,我们添加“懒惰”限定符来解决问题。在各个贪婪运算符后添加“?”能让表达式只匹配<strong>尽可能短</strong>的长度。另外,修改器“U”也能惰化能多次限定的运算符。理解贪婪与懒惰的区别是运用高级正则表达式的基础。</p>
<h4>贪婪操作符</h4>
<p>操作符 * 匹配之前的表达式零次或零次以上。它是一个贪婪操作符。请看下面的例子:</p>
<pre class="blockcode"><code class="language-php">preg_match( &#39;/&lt;h1&gt;.*&lt; \/h1&gt;/&#39;, &#39;&lt;/h1&gt;&lt;h1&gt;这是一个标题。&lt;/h1&gt;
&lt;h1&gt;这是另一个。&lt;/h1&gt;&#39;, $matches );</code></pre>
<p>句点(.)能代表除换行符外的任意字符。上面的正则表达式匹配 h1 标签以及标签内的所有内容。它用句点(.)和星号(*)来匹配标签内的所有内容。匹配结果如下:</p>
<h1>这是一个标题。</h1>
<h1>这是另一个。</h1>
<p>整个字串都被返回。* 操作符会连续匹配所有内容—— 甚至包括中间的 h1 闭合标签。因为它是贪婪的,匹配整个字串是符合其利益最大化原则。</p>
<h4>懒惰操作符</h4>
<p>把上面的式子稍作修改,加上一个问号(?),能让表达式变懒惰:</p>
<pre class="blockcode"><code class="language-php">/&lt;h1&gt;.*?&lt; \/h1&gt;/&lt;/h1&gt;</code></pre>
<p>这样它会觉得,只需匹配到第一个 h1 结尾标签就完成任务了。</p>
<p>另一个有着类似属性的贪婪操作符是 {n,} 。它代表之前的匹配模式重复n次或n次以上,如果没有加上问号,它会寻找尽可能多的重复次数,加上的话,则会尽可能少重复(当然也就是“重复n次”最少)。</p>
<pre class="blockcode"><code class="language-php"># 建立字串
$str &#61; &#39;hihihi oops hi&#39;;
# 使用贪婪的{n,}操作符进行匹配
preg_match( &#39;/(hi){2,}/&#39;, $str, $matches );  # matches[0] 将是 &#39;hihihi&#39;
# 使用堕化了的 {n,}? 操作符匹配
preg_match( &#39;/(hi){2,}?/&#39;, $str, $matches );  # matches[0] 将是 &#39;hihi&#39;</code></pre>
<h3>2. 回返引用(Back referencing)</h3>
<p><img alt="Back Referencing" height="290" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-1e5402c48c6ee07d4e63639b743ce2f4.jpg" width="300"></p>
<h4>有什么用?</h4>
<p><strong>回返引用(Back referencing)</strong>一般被翻译成“反向引用”、“后向引用”、“向后引用”,个人觉得“回返引用”更为贴切[<a href="http://blog.benhuoer.com/" title="笨活儿">笨活儿</a>]。它是在正则表达式内部引用<strong>之前捕获到的内容</strong>的方法。例如,下面这个简单例子的目的是匹配出引号内部的内容:</p>
<pre class="blockcode"><code class="language-php"># 建立匹配数组
$matches &#61; array();
# 建立字串
$str &#61; &#34;\&#34;This is a &#39;string&#39;\&#34;&#34;;
# 用正则表达式捕捉内容
preg_match( &#34;/(\&#34;|&#39;).*?(\&#34;|&#39;)/&#34;, $str, $matches );
# 输出整个匹配字串
echo  $matches[0];</code></pre>
<p>它会输出:</p>
<pre class="blockcode"><code class="language-php">&#34;This is a&#39;</code></pre>
<p>显然,这并不是我们想要的内容。</p>
<p>这个表达式从开头的双引号开始匹配,遭遇单引号之后就错误地结束了匹配。这是因为表达式里说:<code>(&#34;|&#39;)</code>,也就是双引号(<code>&#34;</code>&#xff09
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP