### 前向界定符
另一個零寬界定符(zero-width assertion)是前向界定符。前向界定符包括前向肯定界定符和前項否定界定符,如下所示:
**(?=...)**
前向肯定界定符。如果所含正則表達式,以 ... 表示,在當前位置成功匹配時成功,否則失敗。但一旦所含表達式已經嘗試,匹配引擎根本沒有提高;模式的剩余部分還要嘗試界定符的右邊。
**(?!...)**
前向否定界定符。與肯定界定符相反;當所含表達式不能在字符串當前位置匹配時成功
通過示范在哪前向可以成功有助于具體實現。考慮一個簡單的模式用于匹配一個文件名,并將其通過 "." 分成基本名和擴展名兩部分。如在 "news.rc" 中,"news" 是基本名,"rc" 是文件的擴展名。
匹配模式非常簡單:
```
.*[.].*$
```
注意 "." 需要特殊對待,因為它是一個元字符;我把它放在一個字符類中。另外注意后面的 $; 添加這個是為了確保字符串所有的剩余部分必須被包含在擴展名中。這個正則表達式匹配 "foo.bar"、"autoexec.bat"、 "sendmail.cf" 和 "printers.conf"。
現在,考慮把問題變得復雜點;如果你想匹配的擴展名不是 "bat" 的文件名?一些不正確的嘗試:
```
.*[.][^b].*$
```
上面的第一次去除 "bat" 的嘗試是要求擴展名的第一個字符不是 "b"。這是錯誤的,因為該模式也不能匹配 "foo.bar"。
```
.*[.]([^b]..|.[^a].|..[^t])$
```
當你試著修補第一個解決方法而要求匹配下列情況之一時表達式更亂了:擴展名的第一個字符不是 "b"; 第二個字符不是 "a";或第三個字符不是 "t"。這樣可以接受 "foo.bar" 而拒絕 "autoexec.bat",但這要求只能是三個字符的擴展名而不接受兩個字符的擴展名如 "sendmail.cf"。我們將在努力修補它時再次把該模式變得復雜。
```
.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$
```
在第三次嘗試中,第二和第三個字母都變成可選,為的是允許匹配比三個字符更短的擴展名,如 "sendmail.cf"。
該模式現在變得非常復雜,這使它很難讀懂。更糟的是,如果問題變化了,你想擴展名不是 "bat" 和 "exe",該模式甚至會變得更復雜和混亂。
前向否定把所有這些裁剪成:
```
.*[.](?!bat$).*$
```
前向的意思:如果表達式 bat 在這里沒有匹配,嘗試模式的其余部分;如果 bat$ 匹配,整個模式將失敗。后面的 $ 被要求是為了確保象 "sample.batch" 這樣擴展名以 "bat" 開頭的會被允許。
將另一個文件擴展名排除在外現在也容易;簡單地將其做為可選項放在界定符中。下面的這個模式將以 "bat" 或 "exe" 結尾的文件名排除在外。
```
.*[.](?!bat$|exe$).*$
```