$NEST(start match, [inner match,] end match)$NEST(<a\s[^>]+>,</a>) のように inner match を省略することが出来ます。
開始タグは正しいタグの形をしている必要はなく、$NEST(<a\s,</a>) でも動作します。
inner match を省略した $NEST はアスタリスクで「$NEST の inner match 分」を消費した表現よりも高速に動作します。
$NEST(<a\s,</a>) は <a\s*</a> よりも高速に動作する、という事です。
以下のhtmlソースにマッチさせる表現を考えてみましょう。
htmlソース<divclass="ad"><divclass="ad1"><ahref="http://sample1.ad.com/">広告1</a><ahref="http://sample2.ad.com/">広告2</a><ahref="http://sample3.ad.com/">広告3</a></div><divclass="ad2"><ahref="http://sample1.ad.com/"><imgsrc='http://sample1.ad.com//ad.png'alt='広告1'/></a><ahref="http://sample2.ad.com/"><imgsrc='http://sample2.ad.com//ad.png'alt='広告2'/></a><ahref="http://sample3.ad.com/"><imgsrc='http://sample3.ad.com//ad.png'alt='広告3'/></a></div></div>
上記ソースでは、広告は <div class="ad">...</div> で括られています。$NEST風にマッチさせるなら、以下のようになるでしょうか。
$NEST(<div\s[^>]++class=$AV(ad),</div>)
実際にテストしてみると、ん…? 上半分の広告にしかマッチしませんね。
サンプルコードにマッチした後のhtmlソース<divclass='ad'><ahref='http://sample1.ad.com/'><imgsrc='http://sample1.ad.com//ad.png'alt='広告1'/></a><ahref='http://sample2.ad.com/'><imgsrc='http://sample2.ad.com//ad.png'alt='広告2'/></a><ahref='http://sample3.ad.com/'><imgsrc='http://sample3.ad.com//ad.png'alt='広告3'/></a></div></div>
これは $NEST で陥りがちな失敗です。
$NEST は start match と end match で括られた文字列の入れ子をチェックしています。
つまり、先ほどのコードでは <div\s[^>]++class=$AV(ad) と </div> で括られた文字列をチェックしていたことになります。
中央にある2つのdiv要素には、class= が存在しないため、入れ子とは見なされなかったのです。'ad'
この状況を打開するためには、div要素 に必ずある文字列を start match に入れる必要があります。
$NEST(<div\s,[^>]++class=$AV(ad)*,</div>)
<div\s はどのdiv要素にも含まれていたので、上記表現で入れ子を正しく判定できます。
$NEST(<div,</div>)$NEST(<div\sclass=$AV(ad),</div>)$NEST(<div,\sclass=$AV(ad)*,</div>)当然ですが、$NESTの入れ子チェックで問題になるのは、入れ子がある状況に限ります。
例えば、a要素 は「入れ子を作ってはいけない」とHTMLで決まっているので、$NEST(<a\s[^>]++href=$AV(http://abc.com/*),</a>) と書いて問題ありません。