<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post/2675/</link>
<title><![CDATA[高级正则表达式专题]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Tue, 02 Feb 2010 05:14:10 +0000</pubDate> 
<guid>http://www.jackxiang.com/post/2675/</guid> 
<description>
<![CDATA[ 
	说起正则表达式，可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch和Walter Pitts这两位神经生理学家研究出一种数学方式来描述这些神经网络。<br/><br/>1956年，一位叫Stephen Kleene的美国数学家在McCulloch和Pitts早期工作的基础上，发表了一篇标题为“神经网事件的表示法”的论文，引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式，因此采用“正则表达式”这个术语。<br/><br/>随后，发现可以将这一工作应用于使用Ken Thompson的计算搜索算法的一些早期研究，Ken Thompson是Unix的主要发明人。正则表达式的第一个实用应用程序就是Unix中的qed编辑器。<br/><br/>这个专题主要是为了提高大家对正则表达式的认识和高级的使用。<br/><br/>1 使用正则表达式来检测HTML是否关闭<br/><br/><br/><div class="code">function check_html($html) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;preg_match_all(&quot;/&lt;(&#91;a-zA-Z0-9&#93;+)&#92;&#92;s*&#91;^&#92;&#92;/&gt;&#93;*&gt;/&quot;,$html,$start_tags);<br/>&nbsp;&nbsp;&nbsp;&nbsp;preg_match_all(&quot;/&lt;&#92;&#92;/(&#91;a-zA-Z0-9&#93;+)&gt;/&quot;, $html, $end_tags);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(count($start_tags&#91;1&#93;) != count($end_tags&#91;1&#93;)) return false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;for($i = 0; $i &lt; count($start_tags&#91;1&#93;); $i++) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!in_array($start_tags&#91;1&#93;&#91;$i&#93;, $end_tags&#91;1&#93;)) return false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>&#125;</div><br/><br/>解释：<br/><br/>/&lt;([a-zA-Z0-9]+)&#92;&#92;s*[^&#92;&#92;/&gt;]*&gt;/这个模式是用来匹配HTML的标记（如：&lt;head&gt;、&lt;div&gt;、&lt;div id=&quot;main&quot;&gt;等等，但是除了&lt;br/&gt;这种）的，并且在$start_tags保持着标签的名字（如：head、div等）。而/&lt;&#92;&#92;/([a-zA-Z0-9]+)&gt;/这个模式是用来匹配闭合的HTML标记(如：&lt;/head&gt;,&lt;/div&gt;等)的。并且在$end_tags中保持这闭合的标签名。然后我们用count($start_tags[1]) != count($end_tags[1])这个条件语句来判断开始的标记跟闭合的标记是否相等，不相等就说明没闭合。最后用in_array($start_tags[1][$i], $end_tags[1])来判断开始标跟闭合的标记是否相等。至此，我们就完成了HTML的匹配了！<br/><br/>2 匹配E-mail格式<br/><br/><br/><div class="code">function check_email($email) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(preg_match(&quot;/^&#91;&#92;w&#92;d!#$%&amp;&#039;*+-&#92;/=?^`&#123;&#124;&#125;~&#93;+(&#92;.&#91;&#92;w&#92;d!#$%&amp;&#039;*+-&#92;/=?^`&#123;&#124;&#125;~&#93;+)*@(&#91;a-z&#92;d&#93;&#91;-a-z&#92;d&#93;*&#91;a-z&#92;d&#93;&#92;.)+&#91;a-z&#93;&#91;-a-z&#92;d&#93;*&#91;a-z&#93;$/&quot;, $eamil)) return true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br/>&#125;</div><br/><br/>解释：<br/><br/>不要被/^[&#92;w&#92;d!#$%&amp;&#039;*+-&#92;/=?^`&#123;&#124;&#125;~]+(&#92;.[&#92;w&#92;d!#$%&amp;&#039;*+-&#92;/=?^`&#123;&#124;&#125;~]+)*@([a-z&#92;d][-a-z&#92;d]*[a-z&#92;d]&#92;.)+[a-z][-a-z&#92;d]*[a-z]$/这条模式给吓跑了，其实也很简单的。前部分[&#92;w&#92;d!#$%&amp;&#039;*+-&#92;/=?^`&#123;&#124;&#125;~]+(&#92;.[&#92;w&#92;d!#$%&amp;&#039;*+-&#92;/=?^`&#123;&#124;&#125;~]+)*只是匹配符合RFC-2882标准的E-mail地址允许出现的字符，就是英文字母,数字跟一些符号，有兴趣可以查询RFC-2882手册，而([a-z&#92;d][-a-z&#92;d]*[a-z&#92;d]&#92;.)+就是匹配HOST的。最后[a-z][-a-z&#92;d]*[a-z]就是匹配顶级域名的（如：.com、.org）。<br/><br/>3 非贪心模式<br/><br/>有时候使用正则表达式的时候，你会发现有以下的问题：<br/><br/><br/><div class="code">preg_match(&#039;/&quot;.*&quot;/&#039;, &#039;Tony say:&quot;hello&quot;, Jack say: &quot;Hi&quot;&#039;, $matches);<br/>print_r($matches);</div><br/><br/>很惊奇的你会发现匹配的是这样的内容&quot;hello&quot;, Jack say: &quot;Hi&quot;，而不是&quot;hello&quot;和&quot;Hi&quot;。这就是贪心匹配引起的。在贪心匹配中，正则表达式会尽可能的匹配最多的字符，所以出现了第一种情况，但是我们想要的是第二种情况，那我们要怎么做呢？<br/><br/>我们可以使用非贪心匹配，将刚才的模式改为/&quot;.*?&quot;/这样就可以看见我们想要的结果了。*?这个就是非贪心匹配模式。还有另外一种就是+?。<br/> *?：前面的字符可以出现任意多次，但是遇到*?后的一个字符即停止匹配。<br/> +?：前面的字符可以出现一次或者多次，但是遇到+?后的一个字符即停止匹配。<br/><br/>4 检测一个用户密码是否安全<br/><br/><br/><div class="code">function is_good_pw($pw) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(preg_match(&#039;/(?=.*&#91;0-9&#93;)(?=.*&#91;a-z&#93;)(?=.*&#91;A-Z&#93;).&#123;8,16&#125;/&#039;, $pw)) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return false;<br/>&#125;</div><br/><br/>解释：<br/><br/>在本例中，我们使用了/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).&#123;8,16&#125;/模式来匹配我们的密码。在这个模式中，我们使用了正则表达式中的前瞻模式(?=)。(?=.*[0-9])这个是匹配密码中有数字，而(?=.*[a-z])是匹配密码中有小写字母，最后(?=.*[A-Z])就是匹配密码中有大写字母。而.&#123;8,16&#125;这个就是匹配密码是由8至16个字符组成的。那么我们的密码就需要有数字，大写字母和小写字母组成的就属于安全的密码了～<br/><br/>5 匹配一个网站中的所有链接<br/><br/><br/><div class="code">function get_links($link) &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$html = file_get_contents($link);<br/>&nbsp;&nbsp;&nbsp;&nbsp;$html = str_replace(&quot;&#92;n&quot;, &quot;&quot;, $html);<br/>&nbsp;&nbsp;&nbsp;&nbsp;$html = preg_replace(&#039;/&lt;a/i&#039;, &quot;&#92;n&lt;a&quot;, $html);<br/>&nbsp;&nbsp;&nbsp;&nbsp;$html = preg_replace(&#039;/&lt;&#92;/a&gt;/&#039;, &quot;&lt;/a&gt;&#92;n&quot;, $html);<br/>&nbsp;&nbsp;&nbsp;&nbsp;preg_match_all(&#039;/&lt;a&#92;s*.*&gt;.*?&lt;&#92;/a&gt;/&#039;, $html, $matches);<br/>&nbsp;&nbsp;&nbsp;&nbsp;return($matches);<br/>&#125;</div><br/><br/>在这个例子中，我们想用file_get_contents来取得一个网页的内容。然后用str_replace(&quot;&#92;n&quot;, &quot;&quot;, $html)把所有的换行去掉。再用preg_replace(&#039;/&lt;a/i&#039;, &quot;&#92;n&lt;a&quot;, $html)和preg_replace(&#039;/&lt;&#92;/a&gt;/&#039;, &quot;&lt;/a&gt;&#92;n&quot;, $html)来把所有的&lt;a href=&quot;.....&quot;&gt;.....&lt;/a&gt;模式另起一行。最后就用preg_match_all(&#039;/&lt;a&#92;s*.*&gt;.*?&lt;&#92;/a&gt;/&#039;, $html, $matches)匹配链接模式。/&lt;a&#92;s*.*&gt;.*?&lt;&#92;/a&gt;/就是匹配&lt;a href=&quot;.....&quot;&gt;.....&lt;/a&gt;这种模式的正则表达式。那我们为什么要把&lt;a href=&quot;.....&quot;&gt;.....&lt;/a&gt;链接另起一行呢？？因为在/&lt;a&#92;s*.*&gt;.*?&lt;&#92;/a&gt;/模式中，.*是不能匹配换行的，所以就如&lt;a&gt;和&lt;/a&gt;不在同一行就不能匹配了！！所以我们要这样做！<br/><br/>
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post/2675/#blogcomment51512</link>
<title><![CDATA[[评论] 高级正则表达式专题]]></title> 
<author>二月 &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Tue, 02 Feb 2010 05:22:51 +0000</pubDate> 
<guid>http://www.jackxiang.com/post/2675/#blogcomment51512</guid> 
<description>
<![CDATA[ 
	学到了很多啊。
]]>
</description>
</item>
</channel>
</rss>