<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程默的博客 &#187; 正则表达式</title>
	<atom:link href="http://blog.chacuo.net/tag/%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.chacuo.net</link>
	<description>web原理、web架构、web安全、web性能、服务器性能、服务器架构、服务器安全;你不能预知明天，但你可以利用今天。你不能样样顺利，但你可以事事尽力!</description>
	<lastBuildDate>Mon, 31 Aug 2020 15:33:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>正则表达式性能优化（高效正则表达式书写）</title>
		<link>http://blog.chacuo.net/329.html</link>
		<comments>http://blog.chacuo.net/329.html#comments</comments>
		<pubDate>Thu, 04 Jul 2013 09:25:59 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web性能]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=329</guid>
		<description><![CDATA[这里说的正则表达式优化，主要是针对目前常用的NFA模式正则表达式，详细可以参考：正则表达式匹配解析过程探讨分析 [...]]]></description>
				<content:encoded><![CDATA[<p>这里说的正则表达式优化，主要是针对目前常用的NFA模式正则表达式，详细可以参考：<a href="http://blog.chacuo.net/255.html">正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</a>。从上面例子，我们可以推断出，影响NFA类正则表达式（常见语言：GNU Emacs,Java,ergp,less,more,.NET语言,     <br />PCRE library,Perl,PHP,Python,Ruby,sed,vi )其实主要是它的“回溯”，<u>减少“回溯”次数（减少循环查找同一个字符次数），是提高性能的主要方法。 </u>我们来看个例子：</p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">源字符串：&lt;script type=&quot;text/javascript&quot;&gt;adsfadfsdasfsdafdsfsadfsa&lt;/script&gt;</font></p>
<p><font style="background-color: #ffffff" face="Arial">匹配要求，匹配&lt;script….&gt;….&lt;/script&gt;标签里面所有内容，包括改标签</font></p>
<p><font style="background-color: #ffffff" face="Arial"><strong>常见写法(1)</strong>，因为&lt;script后面可能出现字符、空白、特殊符号等，还有标签里面也可能出现各种js代码。我们简单方法是：</font></p>
<p>正则表达式：&lt;script.*?&gt;.*?&lt;/script&gt; (测试工具使用了：<a title="regexBuddy介绍" href="http://blog.chacuo.net/238.html" rel="regexBuddy介绍" target="_blank">regexBuddy</a>)</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式性能优化" border="0" alt="正则表达式性能优化" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb.png" width="821" height="699" /></a> </pre>
<pre><font color="#0000ff"><u>总共花费115步，回溯了：48次。 </u>因为我们使用”.”字符，匹配默认情况下除了\n之外所有字符。</font></pre>
<p><strong>方法（2）</strong>，我们分析特点发现，&lt;script…&gt;后面，应该是除了”&gt;”之外都可以字符，然后一对&lt;script&gt;标签里面js内容。可以定义为除了”&lt;”之外。（<font color="#0000ff">这里面我只是举例说明优化方法，实际网页中script标签里面，常见都会出现有”&lt;”字符了</font>）</p>
<p>正则表达式：&lt;script[^?&gt;]+&gt;[^&lt;]+&lt;/script&gt;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式性能优化" border="0" alt="正则表达式性能优化" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb1.png" width="808" height="581" /></a> </pre>
<pre><font color="#0000ff"><u>19步，0次回溯！ </u>，步骤只有原先的15%左右，性能几倍的提升了！</font></pre>
</blockquote>
<p>从上面我们看到，不同正则表达式，对通用字符配平，性能相差会很大。减少“回溯”是最好的方法，减少回溯其中最主要的方法是：”用最小范围的元字符，尽量避免用过大的元字符！”。一般规律如下：</p>
<p>1、使用正确的边界匹配器（^、$、\b、\B等），限定搜索字符串位置</p>
<p>2、使用具体的元字符、字符类（\d、\w、\s等） ，少用”.”字符</p>
<p>3、使用正确的量词（+、*、?、{n,m}），如果能够限定长度，匹配最佳</p>
<p>4、使用非捕获组、原子组，减少没有必要的字匹配捕获用(?:) </p>
<p>如：我想匹配一些英文字母，它后面接的是数字。如：abc1234,我可以写 “\w+\d+”，也可以写”[a-zA-Z]+\d+” ，其中第一个\w+会先匹配所有abc1234，然后回溯，匹配满足\d+格式。一共4步，而后面这个只需要2步，步骤减少一半了！好了，今天就先到这里，欢迎大家讨论、交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/329.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式、分组、子匹配（子模式）、非捕获子匹配（子模式）</title>
		<link>http://blog.chacuo.net/289.html</link>
		<comments>http://blog.chacuo.net/289.html#comments</comments>
		<pubDate>Mon, 17 Jun 2013 14:25:25 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=289</guid>
		<description><![CDATA[前面我们知道正则表达式有很多元字符表示匹配次数（量词），都是可以重复匹配前面出现的单个字符次数。有时候，我们可 [...]]]></description>
				<content:encoded><![CDATA[<p>前面我们知道正则表达式有很多元字符表示匹配次数（量词），都是可以重复匹配前面出现的单个字符次数<u><font color="#9b00d3">。有时候，我们可能需要匹配一组多个字符一起出现的次数。这个时候，我们需要分组了。就是用小括号来括起这些字符，指定子表达式(也叫做分组)。</font></u>然后你就可以指定这个子表达式的重复次数了，你也可以对子表达式进行其它一些操作。这个时候，可以把括号中一组字符，看作一个整体了。</p>
<p><strong>分组模式举例说明</strong></p>
<blockquote><pre>如：查找字符串中，连续出现多个win字符串的字符。可以这样完成</pre>
<pre>&#160;</pre>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;this is win winwindows!&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/(win)+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>&#160;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image36.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式分组" border="0" alt="正则表达式分组" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb36.png" width="789" height="526" /></a></pre>
</blockquote>
<p><strong>不用分组模式，同时匹配多个字符，可以吗？</strong> 我们发现以前操作符号：[win]+，尽管可以匹配到winwin字符，因为它代表是有w,i,n组合的一个或者多个字符，不会限制顺序。所见它会匹配到象：wwin,www,inw等等，只要是这3个字符组成的，多个字符都匹配成功了。</p>
<p>上面怎么匹配到，每一个有2个结果呢？这就是子模式（子匹配），默认除了可以将多个字符组合一个整体，另外还会把括号，括起来的这部分表达式存储到一个临时缓冲区中，以便后面正则表达式调用。上面这个例子里面，我们不需要，后期调用的。因此，怎么样屏蔽掉这个子表达式捕获内容呢？ 只需要在：前加上”?:” 即可。我们看看下面例子<u><font color="#9b00d3">正则表达式 分组非捕获模式</font></u>。</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image37.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式 分组非捕获模式" border="0" alt="正则表达式 分组非捕获模式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb37.png" width="787" height="382" /></a></pre>
<pre>&#160;</pre>
</blockquote>
<p>非捕获模式优点有哪些呢？ 从上面看，可以减少捕获，也就会减少匹配次数。因此，在不必要分组表达式加入非捕获前缀”?:”，可以节省内存开销，并且可以提升匹配速度！</p>
<p>刚刚说到了正则表达式分组，默认情况会将子表达式捕获内容，存储到一个缓存区。以便后续调用。 那这个是什么样情况呢？其实，这个是正则表达式的引用。所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容按顺序存储。存储子匹配的缓冲区编号从1开始，最多可以一般存储为9。以便后面表达式引用该值，又叫后向引用。</p>
<blockquote>
<pre>我们看下下面例子，查找一个字符串中，互不相邻，出现多次系统单词：add。</pre>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;add123456addasdf&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/(add)\d+\1/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>&#160;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image38.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式反向引用" border="0" alt="正则表达式反向引用" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb38.png" width="811" height="437" /></a></pre>
</blockquote>
<p>反向引用，常用来处理一些处理一些特殊匹配情况。如：查找字符串中，不相邻重复字符串。查找html一对标签中内容。特别分析html非常常见了(注意，如果使用了反向引用，前面不能屏蔽子匹配捕获，也就是不能加”?:&quot;前缀了)。经常会用：</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://blog.chacuo.net/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/&lt;(\S+)[^&gt;]*&gt;[^&lt;]*&lt;\/\1&gt;/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// (\S+) 表示非显示字符之外所有字符，一般作为html tag名称</span>
<span style="color: #666666; font-style: italic;">// tag格式一般为 &lt;tag   其它属性&gt; 后面[^&gt;]* 匹配tag里面所有其它属性</span>
<span style="color: #666666; font-style: italic;">// 后面的[^&lt;]* 表示 &lt;tag...&gt;中间内容&lt;/tag&gt; 表示中间内容，到&quot;&lt;&quot;结束，因此匹配所有[^&lt;]* 字符</span>
<span style="color: #666666; font-style: italic;">// 最后的&lt;\/\1&gt; &quot;\/&quot; 转义&quot;/&quot;字符，后面的&quot;\1&quot; 表示反向应用前面的(\S+)</span></pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image39.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式匹配html标签" border="0" alt="正则表达式匹配html标签" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb39.png" width="833" height="364" /></a></pre>
<p>&#160;</p>
</blockquote>
<p>以上是正则表达式使用比较重要的，分组，反向匹配，以及非捕获分组说明及实例。希望对要属性改功能朋友有所帮助。同时欢迎朋友们交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/289.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式断言、巡视（Assertions）、正向断言、反向断言</title>
		<link>http://blog.chacuo.net/262.html</link>
		<comments>http://blog.chacuo.net/262.html#comments</comments>
		<pubDate>Fri, 14 Jun 2013 15:50:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=262</guid>
		<description><![CDATA[断言（Assertions）在正则表达式概念里面难理解，它通常指的是在目标字符串的当前匹配位置进行的一种测试但 [...]]]></description>
				<content:encoded><![CDATA[<p>断言（Assertions）在正则表达式概念里面难理解，它通常指的是在目标字符串的当前匹配位置进行的一种测试但这种测试并不占用目标字符串，也即不会移动模式在目标字符串中的当前匹配位置。详细可以看看,<a title="正则表达式匹配过程" href="http://blog.chacuo.net/255.html" rel="正则表达式匹配过程" target="_blank">正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</a>，里面提到“<strong>零宽度</strong>“很多元字符，只是对特殊位置进行匹配，它们可以理解为断言。</p>
<p><strong>断言元字符</strong></p>
<p>常见断言元字符有：&nbsp; \b, \B, \A, \Z, \z, ^ ,$ 它们只是表示特殊位置，各自作用如有字符串AB,带位置表示为：<sub>0</sub>A<sub>1</sub>B<sub>2</sub></p>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" width="935" frame="box">
<thead>
<tr valign="top">
<th width="316">元字符</th>
<th width="617">意义(以上面带位置字符串说明)</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="316"><strong>^</strong></td>
<td valign="top" width="617">行首，字符串首 表示位置0</td>
</tr>
<tr>
<td valign="top" width="316"><strong>$</strong></td>
<td valign="top" width="617">行尾，字符串尾部，表示位置2</td>
</tr>
<tr>
<td valign="top" width="316">\b</td>
<td valign="top" width="617">字分界线，可以表示：0,2位置</td>
</tr>
<tr>
<td valign="top" width="316">\B</td>
<td valign="top" width="617">非字分界线，可以表示1位置</td>
</tr>
<tr>
<td valign="top" width="316">\A</td>
<td valign="top" width="617">目标的开头（独立于多行模式） 表示位置0</td>
</tr>
<tr>
<td valign="top" width="316">\Z</td>
<td valign="top" width="617">目标的结尾或位于结尾的换行符前（独立于多行模式） 表示位置2</td>
</tr>
<tr>
<td valign="top" width="316">\z</td>
<td valign="top" width="617">目标的结尾（独立于多行模式）表示位置2</td>
</tr>
<tr>
<td valign="top" width="316">\G</td>
<td valign="top" width="617">目标中的第一个匹配位置</td>
</tr>
<tr>
<td valign="top" colspan="2">A,Z,z,G很少使用</td>
</tr>
</tbody>
</table>
</blockquote>
<p>这些断言的测试都是一些基于当前位置的测试，断言还支持更多复杂的测试条件。更复杂的断言以子模式方式来表示，它包括先行（前向)断言(Lookahead assertions)和后行（后向）断言(Lookbehind assertions)，这些断言判断只做匹配判断条件，不会记录在匹配结果中，不会匹配字符。</p>
<p><strong>先行断言、正向断言、正向巡视（Lookahead assertions）</strong></p>
<p>先行断言，常有表示（?=pattern)，从当前匹配位置开始测试后面匹配字符串是否成立，还有(?!pattern)这样两种格式，我们来看看一个例子。源字符串：“abc100”，正则表达式是：<br />/[a-z]+(?=\d+)/ ，我们分析下过程如下图：</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image31.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式先行断言、正向断言、正向巡视" border="0" alt="正则表达式先行断言、正向断言、正向巡视" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb31.png" width="842" height="364"></a></pre>
</blockquote>
<p>首先由正则表达式字符 [a-z]+ 取得控制权,匹配字符：”abc”，位置从”0”开始匹配，变成3。从该位置测试/d+是否成立。匹配到字符100，返回成立。因此正则表达式正向断言成功。返回匹配字符串”abc”</p>
<p>(?!pattern) 只是，正向匹配，当后面没有匹配成功，将返回真。以下是系统源字符串：abc100，测试结果如下：</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image32.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式先行断言、正向断言、正向巡视" border="0" alt="正则表达式先行断言、正向断言、正向巡视" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb32.png" width="845" height="330"></a></pre>
<p>&nbsp;</p>
<pre></pre>
</blockquote>
<p><strong>后行断言、反向断言、反向巡视（Lookbehind assertions）</strong></p>
<p>后行断言，常见表达式是：(?&lt;=pattern)或者(?&lt;!pattern)格式。正则表达式里面，不要出现不固定长度量词，可能会出现死循环。匹配出错。表示当前位置左边将出现匹配字符，则返回真，后面匹配正常。因为如果它出现在最左边，默认位置从0开始，匹配都是失败的。一般都从后面正则表达式开始匹配，再回溯，直到匹配到为止。我们看看下面例子：源字符串：“abc100+=“，正则表达式是：”(?&lt;=\w)\w+”，匹配过程如下图：</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image33.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式后行断言、反向断言、反向巡视" border="0" alt="正则表达式后行断言、反向断言、反向巡视" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb33.png" width="850" height="421"></a></pre>
<p>&nbsp;</p>
<pre></pre>
</blockquote>
<p>首先由正则表达式字符 /\w+/取得控制权,匹配字符：”abc100”，位置从”0”开始匹配，匹配到6个字符。从该位置0检测左变\w匹配失败。因此/\w+/从字符b开始匹配到”bc100”，测试它左侧有字符”a”，反向断言正确。因此匹配到字符串“bc100”,(?&lt;!pattern)，只是没有匹配成功返回真，其它都一样！</p>
<p><strong>后记：</strong>从这篇文章，我们发现搜索特点都是从左到有，一般正向断言放到，正则表达式后，反向断言放到匹配正则表达式前。但是，这里也可以放到前或后。这里就不再举例。欢迎交流讨论！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/262.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</title>
		<link>http://blog.chacuo.net/255.html</link>
		<comments>http://blog.chacuo.net/255.html#comments</comments>
		<pubDate>Fri, 14 Jun 2013 10:03:35 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=255</guid>
		<description><![CDATA[已经有多篇关于正则表达式介绍的文章，随着我们越来越多使用正则表达式，想对性能做优化、减少我们正则表达式书写匹配 [...]]]></description>
				<content:encoded><![CDATA[<p>已经有多篇关于正则表达式介绍的文章，随着我们越来越多使用正则表达式，想对性能做优化、减少我们正则表达式书写匹配Bug。我们不得不进一步深入了解正则表达式执行过程了。下面我们一起学习，分析下正则表达式执行过程。我们会用regexbuddy测试工具分解执行过程，具体工具使用，可以看：<a title="正则表达式regexbuddy工具推荐" href="http://blog.chacuo.net/238.html" rel="正则表达式regexbuddy工具推荐">正则表达式性能测试工具推荐、优化工具推荐(regexbuddy推荐)</a>。要了解正则表达式解析过程前，我们先来熟悉几个概念。</p>
<ul>
<li>
<h3><strong>常见正则表达式引擎</strong></h3>
</li>
</ul>
<p>引擎决定了正则表达式匹配方法及内部搜索过程，了解它至关重要的。目前主要流行引擎有：DFA,NFA两种引擎，我们比较区分下。</p>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" width="935" frame="box">
<thead>
<tr valign="top">
<th width="316">引擎</th>
<th width="617">区别点</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="316"><strong>DFA<br /></strong>Deterministic finite automaton <br />确定型有穷自动机</td>
<td valign="top" width="617">DFA引擎它们不要求回溯（并因此它们永远不测试相同的字符两次），所以匹配<strong>速度快</strong>！DFA引擎还可以匹配最长的可能的字符串。不过DFA引擎只包含有限的状态，所以它不能匹配具有反向引用的模式，还<strong>不可以捕获子表达式</strong>。代表性有：<strong>awk,egrep,flex,lex,MySQL,Procmail</strong></td>
</tr>
<tr>
<td valign="top" width="316"><strong>NFA<br /></strong>Non-deterministic finite automaton　非确定型有穷自动机，又分为传统NFA,Posix NFA</td>
<td valign="top" width="617">传统的NFA引擎运行所谓的“贪婪的”匹配回溯算法（longest-leftmost），以指定顺序测试正则表达式的所有可能的扩展并接受第一个匹配项。传统的NFA回溯可以访问完全相同的状态多次，在最坏情况下，它的执行速度可能<strong>非常慢</strong>，但它<strong>支持子匹配</strong>。代表性有：<strong>GNU Emacs,Java,ergp,less,more,.NET语言,<br />PCRE library,Perl,PHP,Python,Ruby,sed,vi等，</strong>一般高级语言都采用该模式。</td>
</tr>
</tbody>
</table>
<p> 
<p>DFA以字符串字符，逐个在正则表达式匹配查找，而NFA以正则表达式为主，在字符串中逐一查找。尽管速度慢，但是对操作者来说更简单，因此应用更广泛！下面所有以NFA引擎举例说明，解析过程！</p>
<p>&nbsp;</p>
</blockquote>
<ul>
<li>
<h3><strong>解析引擎眼中的字符串组成</strong></h3>
</li>
</ul>
<p>对于字符串“DEF”而言，包括D、E、F三个字符和 0、1、2、3 四个数字位置：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，对于正则表达式而言所有源字符串，都有字符和位置。正则表达式会从0号位置，逐个去匹配的。</p>
<ul>
<li>
<h3><strong>占有字符和零宽度</strong></h3>
</li>
</ul>
<p>正则表达式匹配过程中，如果子表达式匹配到的是字符内容，而非位置，并被保存到最终的匹配结果中，那么就认为这个子表达式是占有字符的；如果子表达式匹配的仅仅是位置，或者匹配的内容并不保存到最终的匹配结果中，那么就认为这个子表达式是零宽度的。占有字符是互斥的，零宽度是非互斥的。也就是一个字符，同一时间只能由一个子表达式匹配，而一个位置，却可以同时由多个零宽度的子表达式匹配。常见零宽字符有：^，(?=)等</p>
<ul>
<li>
<h3><strong>正则表达式匹配过程详解实例</strong></h3>
</li>
</ul>
<p>我们掌握了上面几个概念，我们接下来分析下几个常见的解析过程。结合使用软件regexBuddy来分析。</p>
<p><strong>Demo1: </strong>源字符DEF,对应标记是：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，匹配正则表达式是：/DEF/</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image28.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式解析过程" border="0" alt="正则表达式解析过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb28.png" width="855" height="341"></a></pre>
<p>过程可以理解为：首先由正则表达式字符 /D/ 取得控制权，从位置0开始匹配，由 /D/ 来匹配“D”，匹配成功，控制权交给字符 /E/ ；由于“D”已被 /D/ 匹配，所以 /E/ 从位置1开始尝试匹配，由 /E/ 来匹配“E”，匹配成功，控制权交给 /F/ ；由 /F/ 来匹配“F”，匹配成功。 </p>
</blockquote>
<p><strong>Demo2:</strong>源字符DEF,对应标记是：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，匹配正则表达式是：/D\w+F/</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image29.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式解析过程" border="0" alt="正则表达式解析过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb29.png" width="859" height="445"></a> </pre>
<p>过程可以理解为：首先由正则表达式字符 /D/ 取得控制权，从位置0开始匹配，由 /D/ 来匹配“D”，匹配成功，控制权交给字符 /\w+/ ；由于“D”已被 /D/ 匹配，所以 /\w+/ 从位置1开始尝试匹配，\w+贪婪模式，会记录一个备选状态，默认会匹配最长字符，直接匹配到EF，并且匹配成功，当前位置3了。并且把控制权交给 /F/ ；由 /F/ 匹配失败，\w+匹配会回溯一位，当前位置变成2。并把控制权交个/F/，由/F/匹配字符F成功。因此\w+这里匹配E字符,匹配完成！</p>
</blockquote>
<p><strong>Demo3:</strong>源字符DEF,对应标记是：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，匹配正则表达式是：/^(?=D)[D-F]+$/</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image30.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式解析过程" border="0" alt="正则表达式解析过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb30.png" width="862" height="469"></a> </pre>
<p>过程可以理解为：元字符 /^/ 和 /$/ 匹配的只是位置，顺序环视 /(?=D)/ （匹配当前位置，右边是否有字符“D”字符出现）只进行匹配，并不占有字符，也不将匹配的内容保存到最终的匹配结果，所以都是<strong>零宽度</strong>的。 首先由元字符 /^/ 取得控制权，从位置0开始匹配， /^/ 匹配的就是开始位置“位置0”，匹配成功，控制权交给顺序环视 /(?=D)/；/(?=D])/ 要求它所在位置右侧必须是字母”D”才能匹配成功，零宽度的子表达式之间是不互斥的，即同一个位置可以同时由多个零宽度子表达式匹配，所以它也是从位置0尝试进行匹配，位置0的右侧是字符“D”，符合要求，匹配成功，控制权交给 /[D-F]+/ ；因为 /(?=D)/ 只进行匹配，并不将匹配到的内容保存到最后结果，并且 /(?=D)/ 匹配成功的位置是位置0，所以 /[D-F]+/ 也是从位置0开始尝试匹配的， /[D-F]+/ 首先尝试匹配“D”，匹配成功，继续尝试匹配，直到匹配完”EF”，这时已经匹配到位置3，位置3的右侧已没有字符，这时会把控制权交给 /$/，元字符 /$/ 从位置3开始尝试匹配，它匹配的是结束位置，也就是“位置3”，匹配成功。此时正则表达式匹配完成，报告匹配成功。匹配结果为“DEF”，开始位置为0，结束位置为3。其中 /^/ 匹配位置0， /(?=D)/ 匹配位置0， /[D-F]+/ 匹配字符串“DEF”， /$/ 匹配位置3。</p>
<p>&nbsp;</p>
</blockquote>
<p><strong>后记：</strong>上面这几个例子，我们分析了正则表达式普通匹配，还有回溯过程，然后零宽度字符，匹配过程。当然，给出的例子比较简单，实际过程中会遇到更长，更复杂的正则表达式。但是，思想是类似的。只要我们把我解析原理，都可以逐一分解的。好了，就到这里，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/255.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式性能测试工具推荐、优化工具推荐(regexbuddy推荐)</title>
		<link>http://blog.chacuo.net/238.html</link>
		<comments>http://blog.chacuo.net/238.html#comments</comments>
		<pubDate>Thu, 13 Jun 2013 14:59:17 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web性能]]></category>
		<category><![CDATA[学习工具]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=238</guid>
		<description><![CDATA[前不久，我们推荐了个正则表达式入门学习工具。正则表达式工具推荐（学习工具、测试工具） ，今天我们看下，正则表达 [...]]]></description>
				<content:encoded><![CDATA[<p>前不久，我们推荐了个正则表达式入门学习工具。<a href="http://blog.chacuo.net/198.html">正则表达式工具推荐（学习工具、测试工具）</a> ，今天我们看下，正则表达式的性能测试工具。这里我们先说下，为什么需要这样的工具，这个工具有什么作用呢？</p>
<ul>
<li>
<h3><span style="font-weight: bold">为什么需要性能测试工具</span></h3>
</li>
</ul>
<h3></h3>
<p>我们都知道，正则表达式使用进行搜索查找，没有字符串直接查找快！而且性能是几何倍数下降。那么，为什么正则表达式速度会比字符串搜索慢呢。我们来看看，正则表达式查找字符串的匹配过程吧。正则表达式由一些元字符，普通字符，量词字符组合成。默认情况下，这些量词元字符（*,+,?)都是贪婪模式，会最大长度匹配字符串。我们知道，正则表达式往往搜索路径会有多个，我们看看，下面匹配过程。就知道，主要影响正则表达式执行性能有哪些了。</p>
<p>正则表达式匹配过程如：\d+abc，元字符是：”12345bdc”，查找会从左向右进行，\d+，贪婪模式，一下子匹配到12345，然后bdc与\d+不能匹配，”abc”中,”a”字符，开始匹配”bdc”，发现匹配失败。正则表达式开始回溯匹配（贪婪模式量词开始逐一减少匹配字符长度)，\d+只匹配”1234”，”5bdc”与”abc”匹配，任然失败。\d+继续减少匹配长度为：”123”，”45bdc”与”abc”匹配，任然失败。继续回退，直到\d+匹配”1”，用”2345bdc”与”bdc”匹配，任然失败。整个匹配就失败了。</p>
<p>从上面过程中，我们发现，每次回溯，要重新操作匹配因此匹配搜索次数，直接影响正则表达式的性能。做正则表达式性能优化，一般就是优化查询的次数。这个是我们分析过程，如果有个工具能够实实在在看到每一步匹配过程，对于我们优化正则表达式将带来太多方便了。这里介绍工具是：<strong>regexbuddy软件</strong>，它就是一个实实在在看到匹配过程工具。</p>
<ul>
<li>
<h3><span style="font-weight: bold">regexbuddy工具怎么样使用，使用介绍</span></h3>
</li>
</ul>
<blockquote><pre>1、安装完<strong>regexbuddy</strong></pre>
<p></p>
<pre><strong></strong></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image23.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy介绍" border="0" alt="regexbuddy介绍" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb23.png" width="863" height="523"></a></pre>
<p>该工具支持多种程序语言正则表达式，如：perl,pcre,javascript,python,ruby,c#,java等等，还能自动生成程序代码，并且内部带有大量的常用正则表达式。</p>
<pre>2、一般切换到side by side：</pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image24.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy使用" border="0" alt="regexbuddy使用" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb24.png" width="865" height="549"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre>3、匹配过程</pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image25.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy匹配过程" border="0" alt="regexbuddy匹配过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb25.png" width="867" height="524"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image26.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy匹配过程" border="0" alt="regexbuddy匹配过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb26.png" width="866" height="524"></a></pre>
<p>从上面一个匹配看，这个简单一个匹配，搜索了8次，进行了不断查找。如果我们已经准确知道自己要匹配什么样字符，我们可以对源正则表达式修改下，减少匹配次数。就达到优化正则表达式目的，提高匹配效率！</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image27.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy优化正则表达式" border="0" alt="regexbuddy优化正则表达式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb27.png" width="869" height="526"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
</blockquote>
<p><strong>后记：</strong>这个工具是不是很强大呢，你知道在baidu搜索，该关键字：<strong>regexbuddy，</strong>就可以方便下载到。通过该工具，对我们写出好的高性能正则表达式确实能带来很大帮助。有时候可能一个小小修改，自己程序正则表达式匹配速度可能几个数量级的提升。好了，欢迎大家交流，你有好的工具、方法，欢迎留言，可以给更多朋友分享！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/238.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式单行、多行模式简介（使用说明）</title>
		<link>http://blog.chacuo.net/225.html</link>
		<comments>http://blog.chacuo.net/225.html#comments</comments>
		<pubDate>Wed, 12 Jun 2013 14:13:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=225</guid>
		<description><![CDATA[继上几篇正则表达式相关说明（详情：正则表达式 )，我们今天继续讨论下，它的单行，多行模式使用，及容易出现错误地 [...]]]></description>
				<content:encoded><![CDATA[<p>继上几篇正则表达式相关说明（详情：<a title="正则表达式学习" href="http://blog.chacuo.net/tag/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F" target="_blank">正则表达式</a> )，我们今天继续讨论下，它的单行，多行模式使用，及容易出现错误地方。单行，多行模式，都是正则表达式的模式修饰符里面出现的参数。目前常用正则表达式都有该使用选项，如：javascript 正则表达式，一般是：”/正则表达式匹配字符/修饰符“ ，最后一个”/” 后面是修饰符。然后，php也是类似的，c#，python等，一般调用正则表达式的匹配函数，都有一个另外选项的，设置模式。</p>
<ul>
<li>
<h3><font style="font-weight: bold">单行、多行模式容易出现理解错误</font></h3>
</li>
</ul>
<h3><strong></strong></h3>
<p>为什么说，容易出现理解错误呢，它们英文对应说明是：SingleLine ，MultiLine，刚好是单行、多行意思。因此，很多朋友就会从字面理解里面，得出以下结论：（哈哈、刚刚使用，我也是这些朋友中一员）</p>
<p><font color="#ff0000">1、单行，就是从头到尾匹配，多行就是如果匹配字符串，里面有换行符，就匹配到之前</font></p>
<p><font color="#ff0000">2、单行跟多行是冲突的，一次只能指定一个选项，不能同时使用</font></p>
<p>这样来理解其实，很容易就会这样的。我们来看看，官方手册里面怎么说的。</p>
<ul>
<li>
<h3><font style="font-weight: bold">单行、多行模式官方解释</font></h3>
</li>
</ul>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" frame="box">
<thead>
<tr valign="top">
<th width="16%">模式符</th>
<th width="84%">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top">s(单行)</td>
<td valign="top">如果设置了这个修饰符, 模式中的<strong>点号元字符</strong><u>匹配所有字符</u>, 包含换行符. 如果没有这个 修饰符, 点号不匹配换行符</td>
</tr>
<tr>
<td valign="top">m(多行)</td>
<td valign="top">目标字符串是由单行字符组成的(然而实际上它可能会包含多行), &#8220;行首&#8221;元字符(^)仅匹配字符串的开始位置, 而&#8221;行末&#8221;元字符($)仅匹配字符串末尾。当这个修饰符设置之后, &#8220;行首&#8221;和&#8221;行末&#8221;就会匹配目标字符串中任意换行符（\n)之前或之后</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
</blockquote>
<p>通过上面说明，其实这2个修饰符都只是，修改正则表达式常见元字符的匹配范围了。如果加”s”修饰符,元字符”.” 将能够匹配换行符(\n)，如果加”m”修饰符，元字符”$”，将只匹配到”\n”字符前；元字符”^”，将匹配到”\n”字符后。我们还是举例说明吧！（下面关于正则表达式?字符，可以看看前面一节:<a title="正则表达式(regex) 贪婪模式、懒惰模式使用" href="http://blog.chacuo.net/211.html" rel="正则表达式(regex) 贪婪模式、懒惰模式使用">正则表达式(regex) 贪婪模式、懒惰模式使用</a>)</p>
<ul>
<li>
<h3><font style="font-weight: bold">举例，看单行应用</font></h3>
</li>
</ul>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">///读取hao123.com首页</span>
<span style="color: #666666; font-style: italic;">///并且去掉里面script代码</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 *去掉script标签*
 * @author chengmo
 * @copyright http://blog.chacuo.net/
 * @param string $content 原字符串 
 * @param int $style 匹配模式
 * @return string
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> remove_script<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #339933;">,</span><span style="color: #000088;">$style</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$reg</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$style</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span>?<span style="color: #0000ff;">&quot;%&lt;script.*?&gt;.*?&lt;/script&gt;%&quot;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;%&lt;script.*?&gt;.*?&lt;/script&gt;<span style="color: #009933; font-weight: bold;">%s</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reg</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.hao123.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> remove_script<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&amp;</span>nbsp<span style="color: #339933;">;</span></pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image18.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式单行匹配模式" border="0" alt="正则表达式单行匹配模式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb18.png" width="925" height="269"></a></pre>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image19.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式单行匹配模式" border="0" alt="正则表达式单行匹配模式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb19.png" width="928" height="308"></a></pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
</blockquote>
<ul>
<li>
<h3><font style="font-weight: bold">举例，看多行应用</font></h3>
</li>
</ul>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">///读取hao123.com首页</span>
<span style="color: #666666; font-style: italic;">///读取meta标签内容</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 *读取meta标签内容*
 * @author chengmo
 * @copyright http://blog.chacuo.net/
 * @param string $content 原字符串 
 * @param int $style 匹配模式
 * @return string
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> read_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #339933;">,</span><span style="color: #000088;">$style</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$reg</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$style</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span>?<span style="color: #0000ff;">&quot;%^&lt;meta.*?/&gt;%&quot;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;%^&lt;meta.*?&gt;\s+$%m&quot;</span><span style="color: #339933;">;</span>	
	<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reg</span><span style="color: #339933;">,</span><span style="color: #000088;">$content</span><span style="color: #339933;">,</span><span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$arr</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.hao123.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>read_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image20.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式多行" border="0" alt="正则表达式多行" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb20.png" width="863" height="469"></a></pre>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image21.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb21.png" width="868" height="386"></a></pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
</blockquote>
<p><strong>后记：</strong><u><font color="#9b00d3">s，m 修饰符只对，几个特殊元字符有改变。如果你正则表达式中没有那几个元字符。开启s,m字符前后将没有什么变化的。</font></u>对于上面读取hao123.com代码，我们可以继续同时使用s,m模式。如：”%&lt;script.*?&gt;.*?(^currentProfile.*$).*?&lt;/script&gt;%sm” ，匹配所有script标签，并且里面js代码，有一行以curentProfile开头字符串。（以下是正则表达式，单行多行一起使用）</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image22.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式单行多行" border="0" alt="正则表达式单行多行" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb22.png" width="855" height="384"></a></pre>
</blockquote>
<p></script></p>
<pre></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/225.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式(regex) 贪婪模式、懒惰模式使用</title>
		<link>http://blog.chacuo.net/211.html</link>
		<comments>http://blog.chacuo.net/211.html#comments</comments>
		<pubDate>Tue, 11 Jun 2013 14:26:02 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[学习心得]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=211</guid>
		<description><![CDATA[正则表达式贪婪匹配模式，对于初学者，往往也很容易出错。有时候需要匹配一个段代码内容，发现匹配与想要不一致。发现 [...]]]></description>
				<content:encoded><![CDATA[<p>正则表达式贪婪匹配模式，对于初学者，往往也很容易出错。有时候需要匹配一个段代码内容，发现匹配与想要不一致。发现原来，跟贪婪模式有关系。如下，我们看下例子：</p>
<ul>
<li>
<h3><font style="font-weight: bold">什么是贪婪模式</font></h3>
</li>
</ul>
<blockquote><p>字符串有: “&lt;h3&gt;abd&lt;/h3&gt;&lt;h3&gt;bcd&lt;/h3&gt;”，我们想匹配&lt;h3&gt;…&lt;/h3&gt;内容，正则表达式如下：</p>
<p>1、h3开头与结尾，”&lt;h3&gt;待添加&lt;/h3&gt;”&nbsp;&nbsp; &lt;h3&gt;&lt;/h3&gt;都作为普通字符</p>
<p>2、中间可以出现任意字符，个数可以是0个或者多个，正则表达式可以用：.* ，“.”代表任意字符，默认模式不匹配换行,”*” 重复前面字符0个或者多个。</p>
<p>3、最终我们考虑结果将是：”&lt;h3&gt;.*&lt;/h3&gt;” ，也可以是：”&lt;h3&gt;.{0,}&lt;/h3&gt;”&nbsp; ｛｝代表，重复前面指定个数字符，以下用到是，正则表达式调试工具截图，软件可以看：<a href="http://blog.chacuo.net/198.html">正则表达式工具推荐（学习工具、测试工具）</a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image14.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb14.png" width="821" height="450"></a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image15.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb15.png" width="817" height="384"></a></p>
<p>2种结果都一样，这是我们不希望得到的，我们希望从左边开始，第一个出现&lt;/h3&gt;，就开始匹配。以上这种模式，是贪婪模式，也是正则表达式默认以这个方法匹配。表示重复字符，操作符，默认都是贪婪模式，如：.*,.+,.{1,},.{0,} 都会匹配最大长度字符。<u><font color="#0000ff">正则表达式元字符，量词默认首先最大匹配字符串，这些量词有：+,*,?,{m,n} 。一开始匹配，就直接匹配到最长字符串。</font></u></p>
</blockquote>
<ul>
<li>
<h3><font style="font-weight: bold">什么是懒惰模式</font></h3>
</li>
</ul>
<h3><strong></strong></h3>
<p>既然上面几种，表示字符重复个数，元字符默认都是贪婪模式。如果，我们需要最小长度匹配，也就是懒惰模式，怎么样写正则表达式呢？其实，正则表达式里面通用方法是，在表示重复字符元字符，后面加多一个”?”字符即可。上面正则表达式可以写成：”&lt;h3&gt;.*?&lt;/h3&gt;”，或者”&lt;h3&gt;.{0,}?&lt;/h3&gt;” 都可以。</p>
<blockquote><p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image16.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb16.png" width="820" height="405"></a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image17.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb17.png" width="825" height="490"></a></p>
<p>懒惰模式，就匹配到我们需要字符串了。</p>
</blockquote>
<p><strong>总结：</strong>正则表达式，表示字符串重复个数元字符，’?,+,*,{}’ 默认都会选择贪婪模式，会最大长度匹配字符串，而要切换到懒惰模式，就只是在该元字符，后面加多一个”?” 即可切换到非贪婪模式（懒惰模式）。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/211.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式工具推荐（学习工具、测试工具）</title>
		<link>http://blog.chacuo.net/198.html</link>
		<comments>http://blog.chacuo.net/198.html#comments</comments>
		<pubDate>Mon, 10 Jun 2013 15:25:41 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[学习工具]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=198</guid>
		<description><![CDATA[我们学习正则表达式，有个好的工具，对于我们初学者还是不错的选择。这里推荐大家使用：RegExBuilder工具 [...]]]></description>
				<content:encoded><![CDATA[<p>我们学习正则表达式，有个好的工具，对于我们初学者还是不错的选择。这里推荐大家使用：RegExBuilder工具，该工具支持正则表达式多种扩展类型匹配方式，包括：单行，多行，从右向左，忽略大小写等。匹配结果直观显示。截图如下：</p>
<p>&nbsp;</p>
<blockquote><p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image13.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb13.png" width="830" height="490" border="0" /></a></p></blockquote>
<p>将原始字符串输入，就可以在正则表达式窗口写入表达式，一边写一边有提示字符。如果有出错，还有错误提示。下面就会显示匹配到的结果。非常方便！该工具，可以搜索：<a title="搜索：RegExbuider" href="http://www.baidu.com/s?ie=utf-8&amp;bs=regexbuilder&amp;f=8&amp;rsv_bp=1&amp;rsv_spt=3&amp;wd=regexbuilder&amp;inputT=0" target="_blank">regExbuilder</a> ，有好的工具，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/198.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式（regex)入门、元字符(特殊字符)、学习提高、学习实例</title>
		<link>http://blog.chacuo.net/190.html</link>
		<comments>http://blog.chacuo.net/190.html#comments</comments>
		<pubDate>Mon, 10 Jun 2013 10:22:48 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=190</guid>
		<description><![CDATA[什么是正则表达式呢？ 正则表达式，又称正规表示法、常规表示法（英语：Regular Expression，在代 [...]]]></description>
				<content:encoded><![CDATA[<ul>
<li>
<h3><font style="font-weight: bold">什么是正则表达式呢？</font></h3>
</li>
</ul>
<p>正则表达式，又称正规表示法、常规表示法（英语：Regular Expression，在代码中常简写为regex、regexp或RE），它是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。几乎在各种计算机编程语言中都有用到。可以分为普通正则表达式、扩展正则表达式、高级正则表达式。普通正则表达式在linux shell中常用到，高级正则表达式语法规范，基本由perl演化而来。目前常见程序语言（php,perl,python,java,c#)都支持高级正则表达式。</p>
<ul>
<li>
<h3><font style="font-weight: bold">我们为什么要学习正则表达式？</font></h3>
</li>
</ul>
<p>高级程序语言的正则表达式几乎都从perl语言发展而来，因此，语法几乎一致。你学好了，一门正则表达式语言。几乎在所有程序语言中就可以用到。就像，我知道sql语法，后端mysql,mssql几乎都通用。这个也是我们需要学好正则表达式一个原因，通用性。另外一个原因是：正则表达式强大的文本匹配功能。很多文本匹配处理，如果没有正则表达式，还真的很难做出来。如：从一段字符串，读出手机号格式，我们如果用字符串查找，需要做循环，需要写判断。估计耗费不少代码，开发时间。如果用正则表达式，就一行代码就可以了。匹配所有成对的：html标签，如果要做这个，我们发现非常复杂，要处理层次，要匹配标签。一般同人短短几个小时可能完成不了。如果用正则表达式，估计也就几分钟而已。</p>
<ul>
<li>
<h3><font style="font-weight: bold">正则表达式字符串格式</font></h3>
</li>
</ul>
<p>既然我们知道正则表达式重要性，通用性。那么我们对常见格式可以了解下。一般正则表达式由：普通字符+特殊字符（元字符）一起组成的字符串。如：匹配“ab开头，后面紧跟数字字符串“&#160;&#160; “ab\d+”&#160; 这其中ab就是普通字符，\d代表可以是0-9数字，+代表前面字符可以出现1次或以上。哈哈，看起来还真的很容易吧！</p>
<p>正则表达式无论是普通还是扩展还是高级正则表达式。不同之处，可能在特殊字符方面有些不同。很多特殊字符，可以组合，形成一套新匹配规则。这里就不说太深了。我们一般只要知道它的常见元字符。基本上常见正则表达式就可以写出来了。 </p>
<p>以下是javascript 正则表达式常见的<strong>元字符</strong>：</p>
<blockquote><div>
<table class="table" border="1" rules="all" cellspacing="0" frame="box">
<thead>
<tr valign="top">
<th width="16%">字符</th>
<th width="84%">描述</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td width="16%">\</td>
<td width="84%">将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如，&#8217;n&#8217; 匹配字符 &quot;n&quot;。&#8217;\n&#8217; 匹配一个换行符。序列 &#8216;\\&#8217; 匹配 &quot;\&quot; 而 &quot;\(&quot; 则匹配 &quot;(&quot;。</td>
</tr>
<tr valign="top">
<td width="16%">^</td>
<td width="84%">匹配输入字符串的开始位置。如果设置了 <b>RegExp</b> 对象的 <b>Multiline</b> 属性，^ 也匹配 &#8216;\n&#8217; 或 &#8216;\r&#8217; 之后的位置。</td>
</tr>
<tr valign="top">
<td width="16%">$</td>
<td width="84%">匹配输入字符串的结束位置。如果设置了<b>RegExp</b> 对象的 <b>Multiline</b> 属性，$ 也匹配 &#8216;\n&#8217; 或 &#8216;\r&#8217; 之前的位置。</td>
</tr>
<tr valign="top">
<td width="16%">*</td>
<td width="84%">匹配前面的子表达式零次或多次。例如，zo* 能匹配 &quot;z&quot; 以及 &quot;zoo&quot;。 * 等价于{0,}。</td>
</tr>
<tr valign="top">
<td width="16%">+</td>
<td width="84%">匹配前面的子表达式一次或多次。例如，&#8217;zo+&#8217; 能匹配 &quot;zo&quot; 以及 &quot;zoo&quot;，但不能匹配 &quot;z&quot;。+ 等价于 {1,}。</td>
</tr>
<tr valign="top">
<td width="16%">?</td>
<td width="84%">匹配前面的子表达式零次或一次。例如，&quot;do(es)?&quot; 可以匹配 &quot;do&quot; 或 &quot;does&quot; 中的&quot;do&quot; 。? 等价于 {0,1}。</td>
</tr>
<tr valign="top">
<td width="16%">{<i>n</i>}</td>
<td width="84%"><i>n</i> 是一个非负整数。匹配确定的 <i>n</i> 次。例如，&#8217;o{2}&#8217; 不能匹配 &quot;Bob&quot; 中的 &#8216;o&#8217;，但是能匹配 &quot;food&quot; 中的两个 o。</td>
</tr>
<tr valign="top">
<td width="16%">{<i>n</i>,}</td>
<td width="84%"><i>n</i> 是一个非负整数。至少匹配<i>n</i> 次。例如，&#8217;o{2,}&#8217; 不能匹配 &quot;Bob&quot; 中的 &#8216;o&#8217;，但能匹配 &quot;foooood&quot; 中的所有 o。&#8217;o{1,}&#8217; 等价于 &#8216;o+&#8217;。&#8217;o{0,}&#8217; 则等价于 &#8216;o*&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">{<i>n</i>,<i>m</i>}</td>
<td width="84%"><i>m</i> 和 <i>n</i> 均为非负整数，其中<i>n</i> &lt;= <i>m</i>。最少匹配 <i>n</i> 次且最多匹配 <i>m</i> 次。刘， &quot;o{1,3}&quot; 将匹配 &quot;fooooood&quot; 中的前三个 o。&#8217;o{0,1}&#8217; 等价于 &#8216;o?&#8217;。请注意在逗号和两个数之间不能有空格。</td>
</tr>
<tr valign="top">
<td width="16%">?</td>
<td width="84%">当该字符紧跟在任何一个其他限制符 (*, +, ?, {<i>n</i>}, {<i>n</i>,}, {<i>n</i>,<i>m</i>}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 &quot;oooo&quot;，&#8217;o+?&#8217; 将匹配单个 &quot;o&quot;，而 &#8216;o+&#8217; 将匹配所有 &#8216;o&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">.</td>
<td width="84%">匹配除 &quot;\n&quot; 之外的任何单个字符。要匹配包括 &#8216;\n&#8217; 在内的任何字符，请使用象 &#8216;[.\n]&#8216; 的模式。</td>
</tr>
<tr valign="top">
<td width="16%">(<i>pattern</i>)</td>
<td width="84%">匹配<i>pattern</i> 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 <b>SubMatches</b> 集合，在JScript 中则使用 <b>$0</b>…<b>$9</b> 属性。要匹配圆括号字符，请使用 &#8216;\(&#8216; 或 &#8216;\)&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">(?:<i>pattern</i>)</td>
<td width="84%">匹配 <i>pattern</i> 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 &quot;或&quot; 字符 (|) 来组合一个模式的各个部分是很有用。例如， &#8216;industr(?:y|ies) 就是一个比 &#8216;industry|industries&#8217; 更简略的表达式。</td>
</tr>
<tr valign="top">
<td width="16%">(?=<i>pattern</i>)</td>
<td width="84%">正向预查，在任何匹配 <i>pattern</i> 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如， &#8216;Windows (?=95|98|NT|2000)&#8217; 能匹配 &quot;Windows 2000&quot; 中的 &quot;Windows&quot; ，但不能匹配 &quot;Windows 3.1&quot; 中的 &quot;Windows&quot;。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td>
</tr>
<tr valign="top">
<td width="16%">(?!<i>pattern</i>)</td>
<td width="84%">负向预查，在任何不匹配Negative lookahead matches the search string at any point where a string not matching <i>pattern</i> 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如&#8217;Windows (?!95|98|NT|2000)&#8217; 能匹配 &quot;Windows 3.1&quot; 中的 &quot;Windows&quot;，但不能匹配 &quot;Windows 2000&quot; 中的 &quot;Windows&quot;。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始 </td>
</tr>
<tr valign="top">
<td width="16%"><i>x</i>|<i>y</i></td>
<td width="84%">匹配 <i>x</i> 或 <i>y</i>。例如，&#8217;z|food&#8217; 能匹配 &quot;z&quot; 或 &quot;food&quot;。&#8217;(z|f)ood&#8217; 则匹配 &quot;zood&quot; 或 &quot;food&quot;。 </td>
</tr>
<tr valign="top">
<td width="16%">[<i>xyz</i>]</td>
<td width="84%">字符集合。匹配所包含的任意一个字符。例如， &#8216;[abc]&#8216; 可以匹配 &quot;plain&quot; 中的 &#8216;a&#8217;。 </td>
</tr>
<tr valign="top">
<td width="16%">[^<i>xyz</i>]</td>
<td width="84%">负值字符集合。匹配未包含的任意字符。例如， &#8216;[^abc]&#8216; 可以匹配 &quot;plain&quot; 中的&#8217;p'。 </td>
</tr>
<tr valign="top">
<td width="16%">[<i>a-z</i>]</td>
<td width="84%">字符范围。匹配指定范围内的任意字符。例如，&#8217;[a-z]&#8216; 可以匹配 &#8216;a&#8217; 到 &#8216;z&#8217; 范围内的任意小写字母字符。 </td>
</tr>
<tr valign="top">
<td width="16%">[^<i>a-z</i>]</td>
<td width="84%">负值字符范围。匹配任何不在指定范围内的任意字符。例如，&#8217;[^a-z]&#8216; 可以匹配任何不在 &#8216;a&#8217; 到 &#8216;z&#8217; 范围内的任意字符。 </td>
</tr>
<tr valign="top">
<td width="16%">\b</td>
<td width="84%">匹配一个单词边界，也就是指单词和空格间的位置。例如， &#8216;er\b&#8217; 可以匹配&quot;never&quot; 中的 &#8216;er&#8217;，但不能匹配 &quot;verb&quot; 中的 &#8216;er&#8217;。 </td>
</tr>
<tr valign="top">
<td width="16%">\B</td>
<td width="84%">匹配非单词边界。&#8217;er\B&#8217; 能匹配 &quot;verb&quot; 中的 &#8216;er&#8217;，但不能匹配 &quot;never&quot; 中的 &#8216;er&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">\c<i>x</i></td>
<td width="84%">匹配由<i>x</i>指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。 <i>x</i> 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 &#8216;c&#8217; 字符。 </td>
</tr>
<tr valign="top">
<td width="16%">\d</td>
<td width="84%">匹配一个数字字符。等价于 [0-9]。 </td>
</tr>
<tr valign="top">
<td width="16%">\D</td>
<td width="84%">匹配一个非数字字符。等价于 [^0-9]。 </td>
</tr>
<tr valign="top">
<td width="16%">\f</td>
<td width="84%">匹配一个换页符。等价于 \x0c 和 \cL。</td>
</tr>
<tr valign="top">
<td width="16%">\n</td>
<td width="84%">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
</tr>
<tr valign="top">
<td width="16%">\r</td>
<td width="84%">匹配一个回车符。等价于 \x0d 和 \cM。</td>
</tr>
<tr valign="top">
<td width="16%">\s</td>
<td width="84%">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
</tr>
<tr valign="top">
<td width="16%">\S</td>
<td width="84%">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
</tr>
<tr valign="top">
<td width="16%">\t</td>
<td width="84%">匹配一个制表符。等价于 \x09 和 \cI。</td>
</tr>
<tr valign="top">
<td width="16%">\v</td>
<td width="84%">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
</tr>
<tr valign="top">
<td width="16%">\w</td>
<td width="84%">匹配包括下划线的任何单词字符。等价于&#8217;[A-Za-z0-9_]&#8216;。 </td>
</tr>
<tr valign="top">
<td width="16%">\W</td>
<td width="84%">匹配任何非单词字符。等价于 &#8216;[^A-Za-z0-9_]&#8216;。 </td>
</tr>
<tr valign="top">
<td width="16%">\x<i>n</i></td>
<td width="84%">匹配 <i>n</i>，其中 <i>n</i> 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如， &#8216;\x41&#8242; 匹配 &quot;A&quot;。&#8217;\x041&#8242; 则等价于 &#8216;\x04&#8242; &amp; &quot;1&quot;。正则表达式中可以使用 ASCII 编码。.</td>
</tr>
<tr valign="top">
<td width="16%">\<i>num</i></td>
<td width="84%">匹配 <i>num</i>，其中 <i>num</i> 是一个正整数。对所获取的匹配的引用。例如，&#8217;(.)\1&#8242; 匹配两个连续的相同字符。 </td>
</tr>
<tr valign="top">
<td width="16%">\<i>n</i></td>
<td width="84%">标识一个八进制转义值或一个后向引用。如果 \<i>n</i> 之前至少 <i>n</i> 个获取的子表达式，则 <i>n</i> 为后向引用。否则，如果 <i>n</i> 为八进制数字 (0-7)，则 <i>n</i> 为一个八进制转义值。</td>
</tr>
<tr valign="top">
<td width="16%">\<i>nm</i></td>
<td width="84%">标识一个八进制转义值或一个后向引用。如果 \<i>nm</i> 之前至少有is preceded by at least <i>nm</i> 个获取得子表达式，则 <i>nm</i> 为后向引用。如果 \<i>nm</i> 之前至少有 <i>n</i> 个获取，则 <i>n</i> 为一个后跟文字 <i>m </i>的后向引用。如果前面的条件都不满足，若 <i>n</i> 和 <i>m</i> 均为八进制数字 (0-7)，则 \<i>nm</i> 将匹配八进制转义值 <i>nm</i>。</td>
</tr>
<tr valign="top">
<td width="16%">\<i>nml</i></td>
<td width="84%">如果 <i>n</i> 为八进制数字 (0-3)，且 <i>m</i> 和 <i>l</i> 均为八进制数字 (0-7)，则匹配八进制转义值 <i>nml。</i></td>
</tr>
<tr valign="top">
<td width="16%">\u<i>n</i></td>
<td width="84%">匹配 <i>n</i>，其中 <i>n</i> 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。</td>
</tr>
</tbody>
</table></div>
</blockquote>
<p>&#160;</p>
<p>从上面元字符里面，我们看到，很多元字符，实际上可以代表一组普通字符。因此，我们要匹配一些字符串，正则表达式往往会有很多种。如：匹配0-9数字，可以用[0-9],\d,[0123456789] ，这样3种都可以，条条大路通罗马，都是对的。那么那一种正则表达式更好呢，性能更高呢，匹配速度更快呢？通过10万次 循环匹配，发现几种几乎相差不大，\d速度比[0-9快，[0-9]比[0123456789]快。从正则表达式精简]程度方面，\d最简单。使用时候，我们尽量用代表字符集元字符去匹配。精简且速度快！</p>
<ul>
<li>
<h3><font style="font-weight: bold">怎么样书写正则表达式呢？</font></h3>
</li>
</ul>
<h3><strong></strong></h3>
<p>我们写正则表达式，都是从分析匹配字符串特点开始，然后逐步补充其它元字符，普通字符。匹配从左到右。</p>
<p><strong>例如：我们要匹配一个手机号码。</strong></p>
<p>1. 分析字符串特点，手机号码是数字，并且是以1开头，11位长</p>
<p>2.可以写”1\d”&#160;&#160; 1开头，后面跟着数字 也可以是：1[0-9]</p>
<p>3.数字长度是11位 ，继续补充1\d{10} ，后面数字长11字符，也可以是：1[0-9]{10} ；{}里面数字，表示它左边字符可以重复出现次数</p>
<p>4.所有字符必须是11位，因此头尾直接必须满足条件，因此可以是：^1\d{10}$ 了。</p>
<p><strong>例如：我们匹配QQ号码</strong></p>
<p>1.分析QQ号码特点是，号码是 最少是5位数，首位字符非0，最大长度，目前到11位了</p>
<p>2.可以先定义首位字符，[1-9]\d&#160;&#160;&#160; 首位字符是1到9，后面是字符</p>
<p>3.后面字符个数在4到10位 [1-9]\d{4,10}</p>
<p>4.所有字符串必须都满足上面匹配，因为可以写成：^[1-9]\d{4,10}</p>
<p><strong>例如：匹配IP地址</strong></p>
<p>1.分析ip结构是，每节 0-255，中间用”.”分割，一共有4节</p>
<p>2.首先我们写第一个0-255 ，可以分解为0-9 一位数,10-99两位数,100-199三位数,200-249三位数第2节,250-255第四节</p>
<p>[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]&#160;&#160; “|”表示或者，计算优先级最低，左右两边可以是多个元字符普通字符组合字符串为一个整体。</p>
<p>3.这样的字符，有三次重复，中间加”.” ，所以结果是：</p>
<p>[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\. ，因为是点字符是元字符，所有需要转义。这样是不是可以了呢，我们发现有问题，”|”优先级最低，这样会把最后\.字符表，组合为：“25[0-5] \.”了。因此，应该是前面几种情况，后面跟个”.”字符，正确是：([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\. ，这样就达到要求了。我们会发现，实际上每家一个()字符，都一个子匹配，会在匹配结果里面出现()内容。这里我们加()目的是，让优先计算，因此不需要里面子匹配内容。我们可以加忽略子匹配内容字符：?: ，结果将变为：(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\. </p>
<p>4.一段已经匹配到了，然后我们这样需要重复三次，我们可以直接重复上一个表达式3次：</p>
<p>方法一：(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.</p>
<p>方法二：把第一段作为分组，重复3次&#160;&#160;&#160; ((?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3} ，然后同样忽略子匹配结果，可以变为：</p>
<p>(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3} 哈哈，看到这个表达式是不是很晕了，其实一个长的表达式，都是从一点一点加上去的。这个利用到，重复次数，将结果简化不少了。</p>
<p>5.最后还有一段0-255匹配</p>
<p>(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ，也就是在后面加多一个0-255匹配即可，然后在上面再加上头尾限定符，变成了：^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$</p>
<p>下面一个图，是读一段文字里面，所有IP个格式地址</p>
<blockquote><p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image12.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb12.png" width="896" height="379" /></a></p>
<p>其中(?=……)是正向匹配，搜索左边字符串，并且该字符串右边必须满足?=后面匹配成功的才匹配成功！</p>
</blockquote>
<p>&#160;</p>
<p>好了，写了这么些例子，发现一口气能从很简单正则表达式，匹配到这么长的表达式了。是不是感觉有些晕了，其实不奇怪，长的正则表达式都是从简单正则表达式得到。逐步加上去了。 欢迎讨论交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/190.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式（regex)或操作符&#8221;&#124;&#8220;使用易出现功能Bug</title>
		<link>http://blog.chacuo.net/187.html</link>
		<comments>http://blog.chacuo.net/187.html#comments</comments>
		<pubDate>Sun, 09 Jun 2013 11:05:27 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=187</guid>
		<description><![CDATA[接上一篇：正则表达式（regex)错误使用导致功能漏洞 ，我们继续梳理，正则表达式错误使用，导致功能设计漏洞（ [...]]]></description>
				<content:encoded><![CDATA[<p>接上一篇：<a href="http://blog.chacuo.net/183.html">正则表达式（regex)错误使用导致功能漏洞</a> ，我们继续梳理，<strong>正则表达式</strong>错误使用，导致功能设计漏洞（bug），做web方面，需要掌握的知识很多，网站开发这项工作，在国内也就10多年，很多开发人员，都是通过：培训(自学) -&gt;模仿-&gt;做项目 ，这样一个过程。很多就是修修改改后，就成为了web开发工程师。这行入门低，很容易上手。但是想成为大师级的，还是很不容易。需要学习，掌握的知识几十门。而对于刚刚入门同人，很多时候因为缺乏系统学习，理论支持。导致提升有些心有余而力不足啦！因此，出现这些或多或少的功能设计漏洞，是很常见的！</p>
<p>好了，有些跑题了，在做代码走查时候，这类漏洞也是时常出现。我们看下，下面代码：</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$user</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;bcd123张三&quot;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">///匹配用户名中出现abc还有bcd开头，后面紧跟是数字字符</span>
&nbsp;
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/abc|bcd\d+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$user</span><span style="color: #339933;">,</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*结果是
array(1) {
  [0]=&gt;
  array(1) {
    [0]=&gt;
    string(6) &quot;bcd123&quot;
  }
}
*/</span></pre></td></tr></table></div>

<p>查找所有页面出现abc或者bcd开头，后面紧跟数字字符串。通过上面，我们看，正确匹配到bcd123，如果我们输入:$user = “abc123张三”， 发现不能匹配到了。原因是”|”字符，优先级最低，以上写法会变成：匹配abc 或者是bcd\d+ 字符串。</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image11.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb11.png" width="714" height="309" /></a> </p>
<p>以上图，将|，包含到()中。</p>
</blockquote>
<p>&#160;</p>
<p>如果要提升优先级，可以(abc|bcd)\d+ ，匹配所有abc或者bcd 字符串，并且后面紧跟数字的。在使用”|”字符串，注意它的优先级级别低，如果要优先匹配，可以放入（）中。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/187.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式（regex)错误使用导致功能漏洞</title>
		<link>http://blog.chacuo.net/183.html</link>
		<comments>http://blog.chacuo.net/183.html#comments</comments>
		<pubDate>Sat, 08 Jun 2013 14:05:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=183</guid>
		<description><![CDATA[写在前面的话 正则表达式它的强大字符串匹配功能，导致目前在各种程序语言中，都非常流行！它被用来描述或者匹配一系 [...]]]></description>
				<content:encoded><![CDATA[<p><strong>写在前面的话</strong></p>
<p>正则表达式它的强大字符串匹配功能，导致目前在各种程序语言中，都非常流行！它被用来描述或者匹配一系列符合某个句法规则的字符串。很多刚刚使用正则表达式都是从听说这个，然后在要使用时候去网上搜索。 很少人一开始就系统去学习正则表达式，从定义原理使用系统学习。因为，对应初学者觉得它太麻烦了，好多原字符。看到那么长一串字符，就很头痛。因此，也懒得去学习。一般遇到问题，直接去网上搜索。如：“邮箱正则表达式，手机号正则表达式，url正则表达式…..” ，我们发现一个很有意思现象，“怎么邮箱正则表达式可以各种各样，url正则表达式也不相同“，都出都在推荐，都说自己是正确的，到底那个是正确的呢？ </p>
<p>从各异的正则表达式，我们可以得出2个结论。一、正则表达式很灵活，多种方法可以实现同一种结果（条条大路通罗马），二、正则表达式匹配结果需要验证的，复杂正则表达式很容易产生错误匹配。今天，我这里不说正则表达式灵活性，我们看看常见正则表达式错误使用，产生功能漏洞例子。希望，我们在使用时候多多注意。以下例子，来自我工作中审核代码，经常出现例子，也欢迎朋友们补充！</p>
<p><strong>定界符”^$”缺失bug</strong></p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">///检测用户名，只能是字符加数字</span>
&nbsp;
<span style="color: #000088;">$user</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;chengmo8&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;strong&gt;/[0-9a-zA-Z]+/&lt;/strong&gt;&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$user</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;用户名错误！&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>这是很常见的，因为没有定界符，正则表达式搜索，会从$user中，字符中从左向右搜索，指导找到满足条件的字符，就会匹配到，并且返回true，程序将继续执行。我们测试，用户名输入：chengmo8，chengmo8??!，#$chengm，中国cadadf，都可以匹配成功，看似要限制只能字符加数字用户名。实际由于缺乏限定符正则表达式，变成了，<u>只要字符串中包含字母加数字</u>就可以注册。而我们需要的是，从头到尾字符串必须是字母加数字。正则表达式应该是：<font style="background-color: #4f81bd" color="#ffffff">^[0-9a-zA-Z]+$ </font>&#160; ，看似简单，在做从头到尾字符匹配时候，不要忘记了^$字符。一个匹配输入字符开头，一个匹配输入字符结尾（默认换行符前)</p>
<p>这种经常做，手机号，邮箱，url，注册用户名，密码等。都需要有限定符号！</p>
<p><strong>方括号字符&quot;[ ]”中字符使用Bug</strong></p>
<p>在正则表达式中，<u>常见正则表达式原字符（.*?等等）在方括号字符中将变成普通字符。</u> <u>在方括号字符中，表示特殊字符，只有“^-\” 3个字符是特殊字符</u>。其中，“^”字符，在左方括号第一个字符时候，是代表不在后面所有字符中字符！</p>
<p>如：[^0]不能是0字符。而如果是：[0^] ，就代表包含0^字符了。因为：^已经不是左括号最右边一个字符了。 已经跟普通字一样了。“-”字符代表是范围字符，如：[0-9] 代表是匹配0到9直接字符。”\”转义字符，如果想匹配”-“字符，可以[0\-9]，如果要匹配”\”，可以是：[0\\9]，表示“09\” 3个字符了。说这么些，其实就是因为，很多朋友在使用方括号字符时候，经常会弄错特殊字符。</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">///检测用户名，只能是字符加数字</span>
&nbsp;
<span style="color: #000088;">$code</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">///匹配字符范围包含.*?</span>
<span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/[.*?]+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">///匹配字符范围包含a到z 26个字符</span>
<span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/[a-z]+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">///匹配字符范围包含A到z 实际上，是从默认情况ascii表中，A字符到z字符中间，一共48字符</span>
<span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/[A-z]+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">///匹配字符范围包含A到z 是对应ascill码，16进制</span>
<span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/[x41-x7A]+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>font color<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;#ff0000&quot;</span><span style="color: #339933;">&gt;</span><span style="color: #666666; font-style: italic;">///只想匹配字符串and</span>
<span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/[and]/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$code</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">///实际匹配，所有包含a,n,d 组成所有字符，跟顺序无关</span>
<span style="color: #339933;">&lt;/</span>font<span style="color: #339933;">&gt;</span></pre></td></tr></table></div>

</blockquote>
<p>&#160;</p>
<p>加红是经常错误理解，只想匹配and，一旦加入到&quot;[ ]&quot;中字符，可以理解为所有字符组成字符 集合。任意在其中出现字符，就可以匹配，跟顺序无关系！如果真需要匹配这类，按字符分组来，如”and|bnd” 将匹配and字符串，或者是bnd字符串。”|”字符是，字符串或操作符。左右两边连续字符串会组合为一个整体匹配。</p>
<p>好了，今天就整理，常见正则表达式，2种常见错误。欢迎大家交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/183.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
