天空海搁浅的鲸 發表於 2006-9-8 00:00:00

正则表达式的语法

<p>正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。</p>
<p>列目录时, dir *.txt或ls *.txt中的*.txt就不是一个正则表达式,因为这里*与正则式的*的含义是不同的。</p>
<p>正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。&nbsp;</p>
<p>3.1 普通字符</p>
<p>由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。&nbsp;</p>
<p>3.2 非打印字符</p>
<table cellspacing="1" cellpadding="3" bgcolor="#eaeaea" border="1">
<tbody>
    <tr bgcolor="#f0f0f0">
      <th>字符</th>
      <th>含义</th>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\cx</td>
      <td>匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c' 字符。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\f</td>
      <td>匹配一个换页符。等价于 \x0c 和 \cL。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\n</td>
      <td>匹配一个换行符。等价于 \x0a 和 \cJ。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\r</td>
      <td>匹配一个回车符。等价于 \x0d 和 \cM。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\s</td>
      <td>匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\S</td>
      <td>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\t</td>
      <td>匹配一个制表符。等价于 \x09 和 \cI。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\v</td>
      <td>匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
    </tr>
</tbody>
</table>
<p>3.3 特殊字符</p>
<p>所谓特殊字符,就是一些有特殊含义的字符,如上面说的”*.txt”中的*,简单的说就是表示任何字符串的意思。如果要查找文件名中有*的文件,则需要对*进行转义,即在其前加一个\。ls \*.txt。正则表达式有以下特殊字符。</p>
<table cellspacing="1" cellpadding="3" bgcolor="#eaeaea" border="1">
<tbody>
    <tr bgcolor="#f0f0f0">
      <th>特别字符</th>
      <th>说明</th>
    </tr>
    <tr bgcolor="#fafafa">
      <td>$</td>
      <td>匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n' 或 ‘\r'。要匹配 $ 字符本身,请使用 \$。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>( )</td>
      <td>标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>*</td>
      <td>匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>+</td>
      <td>匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>.</td>
      <td>匹配除换行符 \n之外的任何单字符。要匹配 .,请使用 \。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>[</td>
      <td>标记一个中括号表达式的开始。要匹配 [,请使用 \[。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>&#63;</td>
      <td>匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 &#63; 字符,请使用 \&#63;。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\</td>
      <td>将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n' 匹配字符 ‘n'。'\n' 匹配换行符。序列 ‘\\' 匹配 “\”,而 ‘\(' 则匹配 “(”。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>^</td>
      <td>匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{</td>
      <td>标记限定符表达式的开始。要匹配 {,请使用 \{。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>|</td>
      <td>指明两项之间的一个选择。要匹配 |,请使用 \|。</td>
    </tr>
</tbody>
</table>
<p>构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。&nbsp;<br />
<br />
3.4 限定符</p>
<p>限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或&#63;或{n}或{n,}或{n,m}共6种。</p>
<p>*、+和&#63;限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个&#63;就可以实现非贪婪或最小匹配。</p>
<p>正则表达式的限定符有:</p>
<table cellspacing="1" cellpadding="3" bgcolor="#eaeaea" border="1">
<tbody>
    <tr bgcolor="#f0f0f0">
      <th>字符</th>
      <th>描述</th>
    </tr>
    <tr bgcolor="#fafafa">
      <td>*</td>
      <td>匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>+</td>
      <td>匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>&#63;</td>
      <td>匹配前面的子表达式零次或一次。例如,”do(es)&#63;” 可以匹配 “do” 或 “does” 中的”do” 。&#63; 等价于 {0,1}。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{n}</td>
      <td>n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 “Bob” 中的 ‘o',但是能匹配 “food” 中的两个 o。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{n,}</td>
      <td>n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 “Bob” 中的 ‘o',但能匹配 “foooood” 中的所有 o。'o{1,}' 等价于 ‘o+'。'o{0,}' 则等价于 ‘o*'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{n,m}</td>
      <td>m 和 n 均为非负整数,其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。'o{0,1}' 等价于 ‘o&#63;'。请注意在逗号和两个数之间不能有空格。</td>
    </tr>
</tbody>
</table>
<p>&nbsp;3.5 定位符</p>
<p>用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。不能对定位符使用限定符。&nbsp;</p>
<p>3.6 选择</p>
<p>用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用&#63;:放在第一个选项前来消除这种副作用。</p>
<p>其中&#63;:是非捕获元之一,还有两个非捕获元是&#63;=和&#63;!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。&nbsp;</p>
<p>3.7 后向引用</p>
<p>对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从 1 开始,连续编号直至最大 99 个子表达式。每个缓冲区都可以使用 ‘\n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。</p>
<p>可以使用非捕获元字符 ‘&#63;:', ‘&#63;=', or ‘&#63;!' 来忽略对相关匹配的保存。</p>
<p>4. 各种操作符的运算优先级</p>
<p>相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如下:</p>
<table cellspacing="1" cellpadding="3" bgcolor="#eaeaea" border="1">
<tbody>
    <tr bgcolor="#f0f0f0">
      <th bgcolor="#f0f0f0">操作符</th>
      <th>描述</th>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\</td>
      <td>转义符</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>(), (&#63;:), (&#63;=), []</td>
      <td>圆括号和方括号</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>*, +, &#63;, {n}, {n,}, {n,m}</td>
      <td>限定符</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>^, $, \anymetacharacter</td>
      <td>位置和顺序</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>|</td>
      <td>“或”操作</td>
    </tr>
</tbody>
</table>
<p>5. 全部符号解释&nbsp;</p>
<table cellspacing="1" cellpadding="3" bgcolor="#eaeaea" border="1">
<tbody>
    <tr bgcolor="#f0f0f0">
      <th bgcolor="#f0f0f0">字符</th>
      <th>描述</th>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\</td>
      <td>将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,'n' 匹配字符 “n”。'\n' 匹配一个换行符。序列 ‘\\' 匹配 “\” 而 “\(” 则匹配 “(”。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>^</td>
      <td>匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n' 或 ‘\r' 之后的位置。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>$</td>
      <td>匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n' 或 ‘\r' 之前的位置。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>*</td>
      <td>匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>+</td>
      <td>匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>&#63;</td>
      <td>匹配前面的子表达式零次或一次。例如,”do(es)&#63;” 可以匹配 “do” 或 “does” 中的”do” 。&#63; 等价于 {0,1}。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{n}</td>
      <td>n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 “Bob” 中的 ‘o',但是能匹配 “food” 中的两个 o。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{n,}</td>
      <td>n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 “Bob” 中的 ‘o',但能匹配 “foooood” 中的所有 o。'o{1,}' 等价于 ‘o+'。'o{0,}' 则等价于 ‘o*'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>{n,m}</td>
      <td>m 和 n 均为非负整数,其中n &lt;= m。最少匹配 n 次且最多匹配 m 次。例如,”o{1,3}” 将匹配 “fooooood” 中的前三个 o。'o{0,1}' 等价于 ‘o&#63;'。请注意在逗号和两个数之间不能有空格。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>&#63;</td>
      <td>当该字符紧跟在任何一个其他限制符 (*, +, &#63;, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 “oooo”,'o+&#63;' 将匹配单个 “o”,而 ‘o+' 将匹配所有 ‘o'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>.</td>
      <td>匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n' 在内的任何字符,请使用象 ‘[.\n]' 的模式。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>(pattern)</td>
      <td>匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 ‘\(' 或 ‘\)'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>(&#63;:pattern)</td>
      <td>匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符 (|) 来组合一个模式的各个部分是很有用。例如, ‘industr(&#63;:y|ies) 就是一个比 ‘industry|industries' 更简略的表达式。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>(&#63;=pattern)</td>
      <td>正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows (&#63;=95|98|NT|2000)' 能匹配 “Windows 2000″ 中的 “Windows” ,但不能匹配 “Windows 3.1″ 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>(&#63;!pattern)</td>
      <td>负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (&#63;!95|98|NT|2000)' 能匹配 “Windows 3.1″ 中的 “Windows”,但不能匹配 “Windows 2000″ 中的 “Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>x|y</td>
      <td>匹配 x 或 y。例如,'z|food' 能匹配 “z” 或 “food”。'(z|f)ood' 则匹配 “zood” 或 “food”。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td></td>
      <td>字符集合。匹配所包含的任意一个字符。例如, ‘' 可以匹配 “plain” 中的 ‘a'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>[^xyz]</td>
      <td>负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]' 可以匹配 “plain” 中的'p'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td></td>
      <td>字符范围。匹配指定范围内的任意字符。例如,'' 可以匹配 ‘a' 到 ‘z' 范围内的任意小写字母字符。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>[^a-z]</td>
      <td>负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 ‘a' 到 ‘z' 范围内的任意字符。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\b</td>
      <td>匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b' 可以匹配”never” 中的 ‘er',但不能匹配 “verb” 中的 ‘er'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\B</td>
      <td>匹配非单词边界。'er\B' 能匹配 “verb” 中的 ‘er',但不能匹配 “never” 中的 ‘er'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\cx</td>
      <td>匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c' 字符。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\d</td>
      <td>匹配一个数字字符。等价于 。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\D</td>
      <td>匹配一个非数字字符。等价于 [^0-9]。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\f</td>
      <td>匹配一个换页符。等价于 \x0c 和 \cL。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\n</td>
      <td>匹配一个换行符。等价于 \x0a 和 \cJ。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\r</td>
      <td>匹配一个回车符。等价于 \x0d 和 \cM。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\s</td>
      <td>匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\S</td>
      <td>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\t</td>
      <td>匹配一个制表符。等价于 \x09 和 \cI。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\v</td>
      <td>匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\w</td>
      <td>匹配包括下划线的任何单词字符。等价于''。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\W</td>
      <td>匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]'。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\xn</td>
      <td>匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41′ 匹配 “A”。'\x041′ 则等价于 ‘\x04′ &amp; “1″。正则表达式中可以使用 ASCII 编码。.</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\num</td>
      <td>匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1′ 匹配两个连续的相同字符。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\n</td>
      <td>标识一个八进制转义值或一个向后引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\nm</td>
      <td>标识一个八进制转义值或一个向后引用。如果 \nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\nml</td>
      <td>如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>\un</td>
      <td>匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (&#63;)。</td>
    </tr>
</tbody>
</table>
<p><br />
<a name="6"></a>6. 部分例子</p>
<table cellspacing="1" cellpadding="3" bgcolor="#eaeaea" border="1">
<tbody>
    <tr bgcolor="#f0f0f0">
      <th bgcolor="#f0f0f0">正则表达式</th>
      <th>说明</th>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/\b(+) \1\b/gi</td>
      <td>一个单词连续出现的位置</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/(\w+):\/\/([^/:]+)(:\d*)&#63;([^# ]*)/</td>
      <td>将一个URL解析为协议、域、端口及相对路径</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/^(&#63;:Chapter|Section) {0,1}$/</td>
      <td>定位章节的位置</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/[-a-z]/</td>
      <td>A至z共26个字母再加一个-号。</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/ter\b/</td>
      <td>可匹配chapter,而不能terminal</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/\Bapt/</td>
      <td>可匹配chapter,而不能aptitude</td>
    </tr>
    <tr bgcolor="#fafafa">
      <td>/Windows(&#63;=95 |98 |NT )/</td>
      <td>可匹配Windows95或Windows98或WindowsNT,当找到一个匹配后,从Windows后面开始进行下一次</td>
    </tr>
</tbody>
</table>
<p>7. 正则表达式匹配规则</p>
<p>7.1 基本模式匹配</p>
<p>一切从最基本的开始。模式,是正规表达式最基本的元素,它们是一组描述字符串特征的字符。模式可以很简单,由普通的字符串组成,也可以非常复杂,往往用特殊的字符表示一个范围内的字符、重复出现,或表示上下文。例如:</p>
<p>^once</p>
<p>这个模式包含一个特殊的字符^,表示该模式只匹配那些以once开头的字符串。例如该模式与字符串”once upon a time”匹配,与”There once was a man from NewYork”不匹配。正如如^符号表示开头一样,$符号用来匹配那些以给定模式结尾的字符串。</p>
<p>bucket$</p>
<p>这个模式与”Who kept all of this cash in a bucket”匹配,与”buckets”不匹配。字符^和$同时使用时,表示精确匹配(字符串与模式一样)。例如:</p>
<p>^bucket$</p>
<p>只匹配字符串”bucket”。如果一个模式不包括^和$,那么它与任何包含该模式的字符串匹配。例如:模式</p>
<p>once</p>
<p>与字符串</p>
<p>There once was a man from NewYork&nbsp;<br />
Who kept all of his cash in a bucket.</p>
<p>是匹配的。</p>
<p>在该模式中的字母(o-n-c-e)是字面的字符,也就是说,他们表示该字母本身,数字也是一样的。其他一些稍微复杂的字符,如标点符号和白字符(空格、制表符等),要用到转义序列。所有的转义序列都用反斜杠(\)打头。制表符的转义序列是:\t。所以如果我们要检测一个字符串是否以制表符开头,可以用这个模式:</p>
<p>^\t</p>
<p>类似的,用\n表示“新行”,\r表示回车。其他的特殊符号,可以用在前面加上反斜杠,如反斜杠本身用\\表示,句号.用\.表示,以此类推。&nbsp;</p>
<p>7.2 字符簇</p>
<p>在INTERNET的程序中,正规表达式通常用来验证用户的输入。当用户提交一个FORM以后,要判断输入的电话号码、地址、EMAIL地址、信用卡号码等是否有效,用普通的基于字面的字符是不够的。</p>
<p>所以要用一种更自由的描述我们要的模式的办法,它就是字符簇。要建立一个表示所有元音字符的字符簇,就把所有的元音字符放在一个方括号里:</p>
<p></p>
<p>这个模式与任何元音字符匹配,但只能表示一个字符。用连字号可以表示一个字符的范围,如:</p>
<p> //匹配所有的小写字母&nbsp;<br />
//匹配所有的大写字母&nbsp;<br />
//匹配所有的字母&nbsp;<br />
//匹配所有的数字&nbsp;<br />
//匹配所有的数字,句号和减号&nbsp;<br />
[ \f\r\t\n] //匹配所有的白字符</p>
<p>同样的,这些也只表示一个字符,这是一个非常重要的。如果要匹配一个由一个小写字母和一位数字组成的字符串,比如”z2″、”t6″或”g7″,但不是”ab2″、”r2d3″ 或”b52″的话,用这个模式:</p>
<p>^$</p>
<p>尽管代表26个字母的范围,但在这里它只能与第一个字符是小写字母的字符串匹配。</p>
<p>前面曾经提到^表示字符串的开头,但它还有另外一个含义。当在一组方括号里使用^是,它表示“非”或“排除”的意思,常常用来剔除某个字符。还用前面的例子,我们要求第一个字符不能是数字:</p>
<p>^[^0-9]$</p>
<p>这个模式与”&amp;5″、”g7″及”-2″是匹配的,但与”12″、”66″是不匹配的。下面是几个排除特定字符的例子:</p>
<p>[^a-z] //除了小写字母以外的所有字符&nbsp;<br />
[^\\\/\^] //除了(\)(/)(^)之外的所有字符&nbsp;<br />
[^\”\'] //除了双引号(”)和单引号(')之外的所有字符</p>
<p>特殊字符”.” (点,句号)在正规表达式中用来表示除了“新行”之外的所有字符。所以模式”^.5$”与任何两个字符的、以数字5结尾和以其他非“新行”字符开头的字符串匹配。模式”.”可以匹配任何字符串,除了空串和只包括一个“新行”的字符串。</p>
<p>PHP的正规表达式有一些内置的通用字符簇,列表如下:</p>
<p>字符簇含义</p>
<p>[[:alpha:]] 任何字母&nbsp;<br />
[[:digit:]] 任何数字&nbsp;<br />
[[:alnum:]] 任何字母和数字&nbsp;<br />
[[:space:]] 任何白字符&nbsp;<br />
[[:upper:]] 任何大写字母&nbsp;<br />
[[:lower:]] 任何小写字母&nbsp;<br />
[[:punct:]] 任何标点符号&nbsp;<br />
[[:xdigit:]] 任何16进制的数字,相当于&nbsp;</p>
<p>7.3 确定重复出现</p>
<p>到现在为止,你已经知道如何去匹配一个字母或数字,但更多的情况下,可能要匹配一个单词或一组数字。一个单词有若干个字母组成,一组数字有若干个单数组成。跟在字符或字符簇后面的花括号({})用来确定前面的内容的重复出现的次数。</p>
<p>字符簇 含义&nbsp;<br />
^$ 所有的字母和下划线&nbsp;<br />
^[[:alpha:]]{3}$ 所有的3个字母的单词&nbsp;<br />
^a$ 字母a&nbsp;<br />
^a{4}$ aaaa&nbsp;<br />
^a{2,4}$ aa,aaa或aaaa&nbsp;<br />
^a{1,3}$ a,aa或aaa&nbsp;<br />
^a{2,}$ 包含多于两个a的字符串&nbsp;<br />
^a{2,} 如:aardvark和aaab,但apple不行&nbsp;<br />
a{2,} 如:baad和aaa,但Nantucket不行&nbsp;<br />
\t{2} 两个制表符&nbsp;<br />
.{2} 所有的两个字符</p>
<p>这些例子描述了花括号的三种不同的用法。一个数字,{x}的意思是“前面的字符或字符簇只出现x次”;一个数字加逗号,{x,}的意思是“前面的内容出现x或更多的次数”;两个用逗号分隔的数字,{x,y}表示“前面的内容至少出现x次,但不超过y次”。我们可以把模式扩展到更多的单词或数字:</p>
<p>^{1,}$ //所有包含一个以上的字母、数字或下划线的字符串&nbsp;<br />
^{1,}$ //所有的正数&nbsp;<br />
^\-{0,1}{1,}$ //所有的整数&nbsp;<br />
^\-{0,1}{0,}\.{0,1}{0,}$ //所有的小数</p>
<p>最后一个例子不太好理解,是吗?这么看吧:与所有以一个可选的负号(\-{0,1})开头(^)、跟着0个或更多的数字({0,})、和一个可选的小数点(\.{0,1})再跟上0个或多个数字({0,}),并且没有其他任何东西($)。下面你将知道能够使用的更为简单的方法。</p>
<p>特殊字符”&#63;”与{0,1}是相等的,它们都代表着:“0个或1个前面的内容”或“前面的内容是可选的”。所以刚才的例子可以简化为:</p>
<p>^\-&#63;{0,}\.&#63;{0,}$</p>
<p>特殊字符”*”与{0,}是相等的,它们都代表着“0个或多个前面的内容”。最后,字符”+”与 {1,}是相等的,表示“1个或多个前面的内容”,所以上面的4个例子可以写成:</p>
<p>^+$ //所有包含一个以上的字母、数字或下划线的字符串&nbsp;<br />
^+$ //所有的正数&nbsp;<br />
^\-&#63;+$ //所有的整数&nbsp;<br />
^\-&#63;*\.&#63;*$ //所有的小数</p>
<p>当然这并不能从技术上降低正规表达式的复杂性,但可以使它们更容易阅读。</p>
<p>转自:http://blog.sina.com.cn/s/blog_461c24d50100dtnz.html</p>
<p>正则表达式非常有用,查找、匹配、处理字符串、替换和转换字符串,输入输出等。而且各种语言都支持,例如.NET正则库,JDK正则包, Perl, JavaScript等各种脚本语言都支持正则表达式。下面整理一些常用的正则表达式。</p>
<table cellspacing="0" cellpadding="2" border="1">
<tbody>
    <tr>
      <td width="140">
      <p>字符</p>
      </td>
      <td width="483">
      <p>描述</p>
      </td>
    </tr>
    <tr>
      <td width="140">\</td>
      <td width="483">将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。</td>
    </tr>
    <tr>
      <td width="140">^</td>
      <td width="483">匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。</td>
    </tr>
    <tr>
      <td width="140">$</td>
      <td width="483">匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。</td>
    </tr>
    <tr>
      <td width="140">*</td>
      <td width="483">匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。</td>
    </tr>
    <tr>
      <td width="140">+</td>
      <td width="483">匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。</td>
    </tr>
    <tr>
      <td width="140">&#63;</td>
      <td width="483">匹配前面的子表达式零次或一次。例如,"do(es)&#63;" 可以匹配 "do" 或 "does" 中的"do" 。&#63; 等价于 {0,1}。</td>
    </tr>
    <tr>
      <td width="140">{n}</td>
      <td width="483">n&nbsp;是一个非负整数。匹配确定的&nbsp;n&nbsp;次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。</td>
    </tr>
    <tr>
      <td width="140">{n,}</td>
      <td width="483">n&nbsp;是一个非负整数。至少匹配n&nbsp;次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。</td>
    </tr>
    <tr>
      <td width="140">{n,m}</td>
      <td width="483">m&nbsp;和&nbsp;n&nbsp;均为非负整数,其中n&nbsp;&lt;=&nbsp;m。最少匹配&nbsp;n&nbsp;次且最多匹配&nbsp;m&nbsp;次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o&#63;'。请注意在逗号和两个数之间不能有空格。</td>
    </tr>
    <tr>
      <td width="140">&#63;</td>
      <td width="483">当该字符紧跟在任何一个其他限制符 (*, +, &#63;, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+&#63;' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。</td>
    </tr>
    <tr>
      <td width="140">.</td>
      <td width="483">匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。</td>
    </tr>
    <tr>
      <td width="140">(pattern)</td>
      <td width="483">匹配&nbsp;pattern&nbsp;并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用&nbsp;SubMatches&nbsp;集合,在JScript 中则使用&nbsp;$0…$9&nbsp;属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。</td>
    </tr>
    <tr>
      <td width="140">(&#63;:pattern)</td>
      <td width="483">匹配&nbsp;pattern&nbsp;但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(&#63;:y|ies) 就是一个比 'industry|industries' 更简略的表达式。</td>
    </tr>
    <tr>
      <td width="140">(&#63;=pattern)</td>
      <td width="483">正向预查,在任何匹配&nbsp;pattern&nbsp;的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows (&#63;=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。</td>
    </tr>
    <tr>
      <td width="140">(&#63;!pattern)</td>
      <td width="483">负向预查,在任何不匹配&nbsp;pattern&nbsp;的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (&#63;!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始</td>
    </tr>
    <tr>
      <td width="140">x|y</td>
      <td width="483">匹配&nbsp;x&nbsp;或&nbsp;y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。</td>
    </tr>
    <tr>
      <td width="140"></td>
      <td width="483">字符集合。匹配所包含的任意一个字符。例如, '' 可以匹配 "plain" 中的 'a'。</td>
    </tr>
    <tr>
      <td width="140">[^xyz]</td>
      <td width="483">负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。</td>
    </tr>
    <tr>
      <td width="140"></td>
      <td width="483">字符范围。匹配指定范围内的任意字符。例如,'' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。</td>
    </tr>
    <tr>
      <td width="140">[^a-z]</td>
      <td width="483">负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。</td>
    </tr>
    <tr>
      <td width="140">\b</td>
      <td width="483">匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。</td>
    </tr>
    <tr>
      <td width="140">\B</td>
      <td width="483">匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。</td>
    </tr>
    <tr>
      <td width="140">\cx</td>
      <td width="483">匹配由&nbsp;x&nbsp;指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x&nbsp;的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。</td>
    </tr>
    <tr>
      <td width="140">\d</td>
      <td width="483">匹配一个数字字符。等价于 。</td>
    </tr>
    <tr>
      <td width="140">\D</td>
      <td width="483">匹配一个非数字字符。等价于 [^0-9]。</td>
    </tr>
    <tr>
      <td width="140">\f</td>
      <td width="483">匹配一个换页符。等价于 \x0c 和 \cL。</td>
    </tr>
    <tr>
      <td width="140">\n</td>
      <td width="483">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
    </tr>
    <tr>
      <td width="140">\r</td>
      <td width="483">匹配一个回车符。等价于 \x0d 和 \cM。</td>
    </tr>
    <tr>
      <td width="140">\s</td>
      <td width="483">匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
    </tr>
    <tr>
      <td width="140">\S</td>
      <td width="483">
      <p>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</p>
      </td>
    </tr>
    <tr>
      <td width="140">\t</td>
      <td width="483">匹配一个制表符。等价于 \x09 和 \cI。</td>
    </tr>
    <tr>
      <td width="140">\v</td>
      <td width="483">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
    </tr>
    <tr>
      <td width="140">\w</td>
      <td width="483">匹配包括下划线的任何单词字符。等价于''。</td>
    </tr>
    <tr>
      <td width="140">\W</td>
      <td width="483">匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。</td>
    </tr>
    <tr>
      <td width="140">\xn</td>
      <td width="483">匹配&nbsp;n,其中&nbsp;n&nbsp;为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,'\x41' 匹配 "A"。'\x041' 则等价于 '\x04' &amp; "1"。正则表达式中可以使用 ASCII 编码。</td>
    </tr>
    <tr>
      <td width="140">\num</td>
      <td width="483">匹配&nbsp;num,其中&nbsp;num&nbsp;是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。</td>
    </tr>
    <tr>
      <td width="140">\n</td>
      <td width="483">标识一个八进制转义值或一个向后引用。如果 \n&nbsp;之前至少&nbsp;n&nbsp;个获取的子表达式,则&nbsp;n&nbsp;为向后引用。否则,如果&nbsp;n&nbsp;为八进制数字 (0-7),则&nbsp;n&nbsp;为一个八进制转义值。</td>
    </tr>
    <tr>
      <td width="140">\nm</td>
      <td width="483">标识一个八进制转义值或一个向后引用。如果 \nm&nbsp;之前至少有&nbsp;nm&nbsp;个获得子表达式,则&nbsp;nm为向后引用。如果 \nm&nbsp;之前至少有&nbsp;n&nbsp;个获取,则&nbsp;n&nbsp;为一个后跟文字&nbsp;m&nbsp;的向后引用。如果前面的条件都不满足,若&nbsp;n&nbsp;和&nbsp;m&nbsp;均为八进制数字 (0-7),则 \nm&nbsp;将匹配八进制转义值&nbsp;nm。</td>
    </tr>
    <tr>
      <td width="140">\nml</td>
      <td width="483">如果&nbsp;n&nbsp;为八进制数字 (0-3),且&nbsp;m&nbsp;和&nbsp;l&nbsp;均为八进制数字 (0-7),则匹配八进制转义值&nbsp;nml。</td>
    </tr>
    <tr>
      <td width="140">/i</td>
      <td width="483">使正则表达式对大小写不敏感, (&#63;-i)是关闭大小写不敏感&nbsp;<br />
      (&#63;i)te(&#63;-i)st应该匹配TEst,但是不能匹配teST或TEST.</td>
    </tr>
    <tr>
      <td width="140">/s</td>
      <td width="483">开启“单行模式”,即点号“.”匹配新行符</td>
    </tr>
    <tr>
      <td width="140">/m</td>
      <td width="483">开启“多行模式”,即“^”和“$”匹配新行符的前面和后面的位置。</td>
    </tr>
    <tr>
      <td width="140">^*$</td>
      <td width="483">只能输入数字</td>
    </tr>
    <tr>
      <td width="140">^\d{n}$</td>
      <td width="483">只能输入n位的数字</td>
    </tr>
    <tr>
      <td width="140">^\d{n,}$</td>
      <td width="483">只能输入至少n位的数字</td>
    </tr>
    <tr>
      <td width="140">^\d{m,n}$</td>
      <td width="483">只能输入m~n位的数字</td>
    </tr>
    <tr>
      <td width="140">^(0|*)$</td>
      <td width="483">只能输入零和非零开头的数字</td>
    </tr>
    <tr>
      <td width="140">^+(.{2})&#63;$</td>
      <td width="483">只能输入有两位小数的正实数</td>
    </tr>
    <tr>
      <td width="140">^+(.{1,3})&#63;$</td>
      <td width="483">只能输入有1~3位小数的正实数</td>
    </tr>
    <tr>
      <td width="140">^\+&#63;*$</td>
      <td width="483">只能输入非零的正整数</td>
    </tr>
    <tr>
      <td width="140">^\-[]0-9"*$</td>
      <td width="483">只能输入非零的负整数</td>
    </tr>
    <tr>
      <td width="140">^.{3}$</td>
      <td width="483">只能输入长度为3的字符</td>
    </tr>
    <tr>
      <td width="140">^+$</td>
      <td width="483">只能输入由26个英文字母组成的字符串</td>
    </tr>
    <tr>
      <td width="140">^+$</td>
      <td width="483">只能输入由数字和26个英文字母组成的字符串</td>
    </tr>
    <tr>
      <td width="140">^\w+$</td>
      <td width="483">只能输入由数字、26个英文字母或者下划线组成的字符串</td>
    </tr>
    <tr>
      <td width="140">^\w{5,17}$</td>
      <td width="483">验证用户密码:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。</td>
    </tr>
    <tr>
      <td width="140">[^%&amp;',;=&#63;$\x22]+</td>
      <td width="483">验证是否含有^%&amp;',;=&#63;$\"等字符</td>
    </tr>
    <tr>
      <td width="140">^[\u4e00-\u9fa5]{0,}$</td>
      <td width="483">只能输入汉字</td>
    </tr>
    <tr>
      <td width="140">^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$</td>
      <td width="483">验证Email地址</td>
    </tr>
    <tr>
      <td width="140">^http://([\w-]+\.)+[\w-]+(/[\w-./&#63;%&amp;=]*)&#63;$</td>
      <td width="483">验证InternetURL</td>
    </tr>
    <tr>
      <td width="140">^\d{15}|\d{18}$</td>
      <td width="483">验证身份证号(15位或18位数字)</td>
    </tr>
    <tr>
      <td width="140">^((2\d|25|&#63;\d\d&#63;)\.){3}(2\d|25|&#63;\d\d&#63;)$</td>
      <td width="483">验证IP地址</td>
    </tr>
    <tr>
      <td width="140">(\w)\1</td>
      <td width="483">匹配两个两个重叠出现的字符&nbsp;<br />
      <p>例如,"aabbc11asd", 返回结果为aa bb 11三组match</p>
      </td>
    </tr>
    <tr>
      <td width="140">&lt;(&#63;&lt;tag&gt;[^\s&gt;]+)[^&gt;]*&gt;.*&lt;/\k&lt;tag&gt;&gt;</td>
      <td width="483">匹配成对的HTML标签,例如</td>
    </tr>
    <tr>
      <td width="140">(&#63;!)</td>
      <td width="483">
      <p>不出现,负声明 <br />
      下例演示如何取得一个&lt;a&gt;标签对中的全部内容,即使其中包含别的HTML tag。</p>
      <p>string newsContent = @"url:&lt;a href=""1.html""&gt;&lt;img src=""1.gif""&gt;test&lt;span style=""color:red;""&gt;<br />
      <br />
      Regex&lt;/span&gt;&lt;/a&gt;."; <br />
      Regex regEnd = new Regex(@"&lt;\s*a[^&gt;]*&gt;([^&lt;]|&lt;(&#63;!/a))*&lt;\s*/a\s*&gt;",RegexOptions.Multiline);</p>
      </td>
    </tr>
</tbody>
</table>
<p>&nbsp;1. 匹配组</p>
<p>常用的组匹配:(实用)</p>
<p>
<table cellspacing="0" cellpadding="2" border="1">
<tbody>
    <tr>
      <td>
      <p>(exp)</p>
      </td>
      <td>匹配exp并且捕获到一个自动命名的组</td>
    </tr>
    <tr>
      <td>
      <p>(&#63;&lt;name&gt;exp)</p>
      </td>
      <td>匹配exp并且捕获到组'name'</td>
    </tr>
    <tr>
      <td>(&#63;=exp)</td>
      <td>exp出现在声明右侧,但exp不作为匹配&nbsp;<br />
      <br />
      括号中的模式必须出现在声明右侧,但不作为匹配的一部分 ,例如:&nbsp;<br />
      <br />
      输入:&nbsp;public keywod&nbsp;string "abc";&nbsp;<br />
      正则:\b\w+(&#63;=ing\b),返回“str”,&nbsp;<br />
      意思为:匹配以ing结束的单词,但ing不作为返回</td>
    </tr>
    <tr>
      <td>(&#63;&lt;=exp)</td>
      <td>exp出现在声明左侧,但exp不作为匹配&nbsp;<br />
      <br />
      括号中的模式必须出现在声明左侧,但不作为匹配的一部分 ,例如:&nbsp;<br />
      <br />
      输入: public remember&nbsp;string "abc";&nbsp;<br />
      正则:(&#63;&lt;=\bre)\w+\b,返回“member”,&nbsp;<br />
      意思为:匹配以re开头的单词,但re不作为返回</td>
    </tr>
    <tr>
      <td>
      <p>(&#63;!exp)</p>
      </td>
      <td>exp不出现在声明右侧,但exp不作为匹配&nbsp;<br />
      <br />
      括号中的模式必须不出现在声明右侧 ,例如:&nbsp;<br />
      <br />
      输入: remember&nbsp;aqa&nbsp;bqu "abc";&nbsp;<br />
      正则:\b\w*q(&#63;!u)\w*\b,返回“aqa”,&nbsp;<br />
      意思为:匹配带q后面不是跟随u的单词</td>
    </tr>
    <tr>
      <td>
      <p>(&#63;&lt;!exp)</p>
      </td>
      <td>exp不出现在声明左侧,但exp不作为匹配&nbsp;</td>
    </tr>
</tbody>
</table>
</p>
<p>输入:public string keywod = "abc"; string value = "test";</p>
<p>目的:匹配 关键字="",例如获得关键字keyword,value;获得等于的值abc和test</p>
<p>表达式:string (&#63;&lt;x&gt;[^=]*&#63;) *= *(&#63;&lt;y&gt;[^;]*&#63;);</p>
<p>代码:</p>
<div class="jb51code">
<pre class="brush:csharp;">
private void ParseKeywords(string input)
{
System.Text.RegularExpressions.MatchCollection mc =
System.Text.RegularExpressions.Regex.Matches(input, @"string (&#63;&lt;x&gt;[^=]*&#63;) *= *(&#63;&lt;y&gt;[^;]*&#63;);");

if (mc != null &amp;&amp; mc.Count &gt; 0)
{
foreach (System.Text.RegularExpressions.Match m in mc)
{
string keyword = m.Groups["x"].Value;
string value = m.Groups["y"].Value;
}
}
}</pre>
</div>
<p>2. 匹配并替换</p>
<p>输入:public &lt;%=classname%&gt;Extension : IExt</p>
<p>目的:匹配 &lt;%= %&gt;中间的classname并替换</p>
<p>表达式:&lt;%=.*%&gt;</p>
<p>代码:</p>
<div class="jb51code">
<pre class="brush:csharp;">
private string Replace(string input)
{
return Regex.Replace(input, @"&lt;%=.*%&gt;", new MatchEvaluator(RefineCodeTag), RegexOptions.Singleline);
}

string RefineCodeTag(Match m)
{
string x = m.ToString();

x = Regex.Replace(x, "&lt;%=", "");
x = Regex.Replace(x, "%&gt;", "");

return x.Trim() + ",";
}</pre>
</div>
<p>正则表达式选项RegexOptions:</p>
<p>
<table cellspacing="0" cellpadding="2" border="1">
<tbody>
    <tr>
      <td>
      <p>ExplicitCapture</p>
      </td>
      <td>n</td>
      <td>
      <p>只有定义了命名或编号的组才捕获</p>
      </td>
    </tr>
    <tr>
      <td>IgnoreCase</td>
      <td>i</td>
      <td>不区分大小写</td>
    </tr>
    <tr>
      <td>IgnorePatternWhitespace</td>
      <td>x</td>
      <td>消除模式中的非转义空白并启用由 # 标记的注释。</td>
    </tr>
    <tr>
      <td>MultiLine</td>
      <td>m</td>
      <td>
      <p>多行模式,其原理是修改了^和$的含义</p>
      </td>
    </tr>
    <tr>
      <td>SingleLine</td>
      <td>s</td>
      <td>
      <p>单行模式,和MultiLine相对应</p>
      </td>
    </tr>
</tbody>
</table>
</p>
<p>正则表达式替换的其他功能:</p>
<p>
<table cellspacing="0" cellpadding="2" border="1">
<tbody>
    <tr>
      <td>$number</td>
      <td>把匹配的第number组替换成替换表达式&nbsp;<br />
      <br />
      <p>这段代码返回的是 “01 012 03 05”</p>
      <p>就是说,对组一的每个匹配结果都用"0$1"这个表达式来替换,"0$1"中"$1"由组1匹配的结果代入</p>
      <div>public static void Main()<br />
      { <br />
      string s = "1 12 3 5";<br />
      s = Regex.Replace(s,@"(\d+)(&#63;#这个是注释)","0$1",RegexOptions.Compiled|RegexOptions.IgnoreCase);<br />
      Console.WriteLine(s);<br />
      Console.ReadLine();<br />
      }<br />
      </div>
      </td>
    </tr>
    <tr>
      <td>
      <p>${name}</p>
      </td>
      <td>
      <p>把匹配的组名为"name"的组替换成表达式,</p>
      <p>上例的Regex expression改成@"(&#63;&lt;name&gt;\d+)(&#63;#这个是注释)"后面的替换式改为"0${name}"结果是一样的</p>
      </td>
    </tr>
    <tr>
      <td>
      <p>$$</p>
      </td>
      <td>
      <p>做$的转义符,如上例表达式改成@"(&#63;&lt;name&gt;\d+)(&#63;#这个是注释)"和"$$${name}",则结果为"$1 $12 $3 $5"</p>
      </td>
    </tr>
    <tr>
      <td>$&amp;</td>
      <td>替换整个匹配</td>
    </tr>
    <tr>
      <td>$`</td>
      <td>替换匹配前的字符</td>
    </tr>
    <tr>
      <td>$'</td>
      <td>替换匹配后的字符</td>
    </tr>
    <tr>
      <td>$+</td>
      <td>替换最后匹配的组</td>
    </tr>
    <tr>
      <td>$_</td>
      <td>替换整个字符串</td>
    </tr>
</tbody>
</table>
</p>
<p>3. 匹配URL中文件名</p>
<blockquote>
<p>输入://www.jb51.net/page1.htm</p>
<p>目的:从URL地址中提取文件名</p>
<p>表达式:s=s.replace(/(.*\/){0,}([^\.]+).*/ig,"$2") ;</p>
<p>代码:</p>
<p>string s = "//www.jb51.net/page1.htm";&nbsp;<br />
s = s.replace(/(.*\/){0,}([^\.]+).*/ig, "$2") ;&nbsp;</p>
</blockquote><blockquote>
<p>一、校验数字的表达式</p>
<p>1 数字:^*$&nbsp;</p>
<p>2 n位的数字:^\d{n}$</p>
<p>3 至少n位的数字:^\d{n,}$&nbsp;</p>
<p>4 m-n位的数字:^\d{m,n}$&nbsp;</p>
<p>5 零和非零开头的数字:^(0|*)$&nbsp;</p>
<p>6 非零开头的最多带两位小数的数字:^(*)+(.{1,2})&#63;$&nbsp;</p>
<p>7 带1-2位小数的正数或负数:^(\-)&#63;\d+(\.\d{1,2})&#63;$&nbsp;</p>
<p>8 正数、负数、和小数:^(\-|\+)&#63;\d+(\.\d+)&#63;$&nbsp;</p>
<p>9 有两位小数的正实数:^+(.{2})&#63;$</p>
<p>10 有1~3位小数的正实数:^+(.{1,3})&#63;$</p>
<p>11 非零的正整数:^\d*$ 或 ^(*){1,3}$ 或 ^\+&#63;*$</p>
<p>12 非零的负整数:^\-[]0-9"*$ 或 ^-\d*$</p>
<p>13 非负整数:^\d+$ 或 ^\d*|0$</p>
<p>14 非正整数:^-\d*|0$ 或 ^((-\d+)|(0+))$</p>
<p>15 非负浮点数:^\d+(\.\d+)&#63;$ 或 ^\d*\.\d*|0\.\d*\d*|0&#63;\.0+|0$</p>
<p>16 非正浮点数:^((-\d+(\.\d+)&#63;)|(0+(\.0+)&#63;))$ 或 ^(-(\d*\.\d*|0\.\d*\d*))|0&#63;\.0+|0$</p>
<p>17 正浮点数:^\d*\.\d*|0\.\d*\d*$ 或 ^((+\.**)|(**\.+)|(**))$</p>
<p>18 负浮点数:^-(\d*\.\d*|0\.\d*\d*)$ 或 ^(-((+\.**)|(**\.+)|(**)))$</p>
<p>19 浮点数:^(-&#63;\d+)(\.\d+)&#63;$ 或 ^-&#63;(\d*\.\d*|0\.\d*\d*|0&#63;\.0+|0)$</p>
<p>二、校验字符的表达式</p>
<p>1 汉字:^[\u4e00-\u9fa5]{0,}$&nbsp;</p>
<p>2 英文和数字:^+$ 或 ^{4,40}$&nbsp;</p>
<p>3 长度为3-20的所有字符:^.{3,20}$&nbsp;</p>
<p>4 由26个英文字母组成的字符串:^+$&nbsp;</p>
<p>5 由26个大写英文字母组成的字符串:^+$&nbsp;</p>
<p>6 由26个小写英文字母组成的字符串:^+$&nbsp;</p>
<p>7 由数字和26个英文字母组成的字符串:^+$&nbsp;</p>
<p>8 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$&nbsp;</p>
<p>9 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$</p>
<p>10 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$</p>
<p>11 可以输入含有^%&amp;',;=&#63;$\"等字符:[^%&amp;',;=&#63;$\x22]+</p>
<p>12 禁止输入含有~的字符:[^~\x22]+</p>
<p>三、特殊需求表达式</p>
<p>1 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$&nbsp;</p>
<p>2 域名:[-a-zA-Z0-9]{0,62}(/.[-a-zA-Z0-9]{0,62})+/.&#63;&nbsp;</p>
<p>3 InternetURL:+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./&#63;%&amp;=]*)&#63;$&nbsp;</p>
<p>4 手机号码:^(13|14|15|18)\d{8}$&nbsp;</p>
<p>5 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)&#63;\d{7,8}$&nbsp;&nbsp;</p>
<p>6 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}&nbsp;</p>
<p>7 身份证号(15位、18位数字):^\d{15}|\d{18}$&nbsp;</p>
<p>8 短身份证号码(数字、字母x结尾):^(){7,18}(x|X)&#63;$ 或 ^\d{8,18}|{8,18}|{8,18}&#63;$&nbsp;</p>
<p>9 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^{4,15}$</p>
<p>10 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^\w{5,17}$</p>
<p>11 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(&#63;=.*\d)(&#63;=.*)(&#63;=.*).{8,10}$</p>
<p>12 日期格式:^\d{4}-\d{1,2}-\d{1,2}</p>
<p>13 一年的12个月(01~09和1~12):^(0&#63;|1)$</p>
<p>14 一个月的31天(01~09和1~31):^((0&#63;)|((1|2))|30|31)$</p>
<p>15 钱的输入格式:</p>
<p>16 1.有四种钱的表示形式我们可以接受:"10000.00" 和 "10,000.00", 和没有 "分" 的 "10000" 和 "10,000":^*$</p>
<p>17 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|*)$</p>
<p>18 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-&#63;*)$</p>
<p>19 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^+(.+)&#63;$</p>
<p>20 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10" 和 "10.2" 是通过的:^+(.{2})&#63;$</p>
<p>21 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^+(.{1,2})&#63;$</p>
<p>22 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^{1,3}(,{3})*(.{1,2})&#63;$</p>
<p>23 8.1到3个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^(+|{1,3}(,{3})*)(.{1,2})&#63;$</p>
<p>24 备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么&#63;)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里</p>
<p>25 xml文件:^(+-&#63;)++\\.$</p>
<p>26 中文字符的正则表达式:[\u4e00-\u9fa5]</p>
<p>27 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))</p>
<p>28 空白行的正则表达式:\n\s*\r (可以用来删除空白行)</p>
<p>29 HTML标记的正则表达式:&lt;(\S*&#63;)[^&gt;]*&gt;.*&#63;&lt;/\1&gt;|&lt;.*&#63; /&gt; (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)</p>
<p>30 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)</p>
<p>31 腾讯QQ号:{4,} (腾讯QQ号从10000开始)</p>
<p>32 中国邮政编码:\d{5}(&#63;!\d) (中国邮政编码为6位数字) 33 IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用) 34 IP地址:((&#63;:(&#63;:25|2\\d|&#63;\\d&#63;\\d)\\.){3}(&#63;:25|2\\d| &#63;\\d&#63;\\d))</p>
</blockquote>
頁: [1]
查看完整版本: 正则表达式的语法