正規表示式與 Kleene 定理
反向參照(backreference)
想像一條規則:「一個字詞,稍後再出現完全相同的那個字詞」。純粹的正規表示式說不出這件事,因為它對先前某部分實際匹配到什麼毫無記憶,只記得樣式的形狀。反向參照是程式 regex 引擎為突破這個限制而加上的功能:它讓一個樣式回頭參照先前某個群組所捕捉到的字面文字。
在多數引擎中,你用括號捕捉一段文字,稍後再用一個帶編號的參照來引用它。例如樣式 (.+)\1 意指「一些非空文字,緊接著再出現那同一段文字」,所以它匹配 abab 與 hellohello,卻不匹配 abcd。那個 \1 並不是重新匹配樣式 (.+);它要求的是第一個群組這一次實際捕捉到的相同字元。那是根本不同的能力:引擎必須記住並比較具體的子字串,而不只是追蹤自己處於哪個狀態。
這正是工程 regex 把數學理論拋在身後的確切之處。像「ww,對某個字串 w」(一個字詞重複)這樣的語言被證明不是正規的,甚至不是上下文無關的,然而單一個反向參照就能表達它。所以一個使用反向參照的樣式不再描述正規語言,Kleene 定理與那些自動機構造也不再適用於它。反向參照很有用(匹配重複的字詞、同類型的成對引號),但它也是最該為 regex 匹配變慢、或在最壞情況下變成 NP 困難負責的功能。
(.+)\1 匹配一個由某段文字重複兩次而成的字串:abcabc 匹配(群組捕捉到 abc),但 abcabd 不匹配。這所表達的語言「ww」不是正規的,所以沒有有限自動機能識別它。
反向參照要求相同的重複文字,這已超出正規之外。
反向參照使一個樣式變得非正規:它能匹配沒有有限自動機能識別的語言,所以即使引擎稱它為正規表示式,它在數學意義上並不是。
又称
另见