1. 程式人生 > >正則表示式的貪婪與非貪婪模式

正則表示式的貪婪與非貪婪模式

<script>
try{
str="<p>abcdefg</p><p>abcdefghijkl</p>";

re1=str.match(/<p>[\W\w]+?<\/p>/ig);
alert("非貪婪模式:\r\n\r\n1:"+re1[0]+"\r\n2:"+re1[1]);

re1=str.match(/<p>[\W\w]+<\/p>/ig);
alert("貪婪模式:\r\n\r\n"+re1);

re1=str.match(/<p>(.+?)<\/p>/i);
alert("非貪婪模式,且不要標記:\r\n\r\n1:"+re1[1]);

re1=str.match(/<p>(.+)<\/p>/i);
alert("貪婪模式,且不要標記:\r\n\r\n"+re1[1]);
}catch(e){alert(e.description)}
</script>

匹配次數中的貪婪與非貪婪

    在使用修飾匹配次數的特殊符號時,有幾種表示方法可以使同一個表示式能夠匹配不同的次數,比如:"{m,n}", "{m,}", "?", "*", "+",具體匹配的次數隨被匹配的字串而定。這種重複匹配不定次數的表示式在匹配過程中,總是儘可能多的匹配。比如,針對文字 "dxxxdxxxd",舉例如下:

表示式

匹配結果

"\w+" 將匹配第一個 "d" 之後的所有字元 "xxxdxxxd"

"\w+" 將匹配第一個 "d" 和最後一個 "d" 之間的所有字元 "xxxdxxx"。雖然 "\w+" 也能夠匹配上最後一個 "d",但是為了使整個表示式匹配成功,"\w+" 可以 "讓出" 它本來能夠匹配的最後一個 "d"

    由此可見,"\w+" 在匹配的時候,總是儘可能多的匹配符合它規則的字元。雖然第二個舉例中,它沒有匹配最後一個 "d",但那也是為了讓整個表示式能夠匹配成功。同理,帶 "*" 和 "{m,n}" 的表示式都是儘可能地多匹配,帶 "?" 的表示式在可匹配可不匹配的時候,也是儘可能的 "要匹配"。這 種匹配原則就叫作 "貪婪" 模式 。

    非貪婪模式:

    在修飾匹配次數的特殊符號後再加上一個 "?" 號,則可以使匹配次數不定的表示式儘可能少的匹配,使可匹配可不匹配的表示式,儘可能的 "不匹配"。這種匹配原則叫作 "非貪婪" 模式,也叫作 "勉強" 模式。如果少匹配就會導致整個表示式匹配失敗的時候,與貪婪模式類似,非貪婪模式會最小限度的再匹配一些,以使整個表示式匹配成功。舉例如下,針對文字 "dxxxdxxxd" 舉例:

表示式

匹配結果

"\w+?" 將盡可能少的匹配第一個 "d" 之後的字元,結果是:"\w+?" 只匹配了一個 "x"

為了讓整個表示式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以讓後邊的 "d" 匹配,從而使整個表示式匹配成功。因此,結果是:"\w+?" 匹配 "xxx"

    更多的情況,舉例如下:

    舉例1:表示式 "<td>(.*)</td>" 與字串 "<td><p>aa</p></td> <td><p>bb</p></td>" 匹配時,匹配的結果是:成功;匹配到的內容是 "<td><p>aa</p></td> <td><p>bb</p></td>" 整個字串, 表示式中的 "</td>" 將與字串中最後一個 "</td>" 匹配。 

    舉例2:相比之下,表示式 "<td>(.*?)</td>" 匹配舉例1中同樣的字串時,將只得到 "<td><p>aa</p></td>", 再次匹配下一個時,可以得到第二個 "<td><p>bb</p></td>"。