1940 年代神經生理學研究 → 1956 年 Stephen Kleene 定義「正則集」與代數系統 → 1968 年 Ken Thompson 引入計算機領域 (qed, grep) → 1980 年代 Bell Labs & UCB 研究 grep 引擎 → Alfred Aho 發明 Egrep/awk → 1986 年 Henry Spencer 發布 C 庫 → Larry Wall 發布 Perl 奠定現代標準。
| 維度 | DFA (確定性有限自動機) | NFA (非確定性有限自動機) |
|---|---|---|
| 匹配策略 | 掃描文本,對每字符僅處理一次 | 掃描正則,吃字符、回溯、吐字符 |
| 速度 | 快,O(n) | 慢,最差指數級(回溯陷阱) |
| 功能豐富度 | 低 | 高 (支援懶惰量詞、反向引用、條件判斷等) |
| 主流引擎 | awk, egrep, flex, lex, MySQL, Procmail | Perl, PCRE, Java, .NET, Python, Ruby, PHP, grep, vi |
| 優先匹配規則 | 最長左邊優先 | 最左子表達式優先 |
| 預設量詞 | 無概念 | 貪婪 |
perl 成功 → 記錄並停止 → 錯過更長匹配。perlman 更長 → 選擇最長匹配。修正寫法: NFA 下應寫為 /perlman|perl/,讓更長分支優先嘗試。
正則: (a*)*b
文本: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaac
指數級回溯導致效能崩潰。解決:使用原子組、佔有優先量詞或改用 DFA 引擎。
a+ = aa*、a? = (a|ε)、補集 (~)。| 類型 | 代表程式/庫 |
|---|---|
| DFA | awk, egrep, flex, lex, MySQL, Procmail |
| 傳統 NFA | GNU Emacs, Java, grep, less, more, .NET, PCRE, Perl, PHP, Python, Ruby, sed, vi |
| POSIX NFA | mawk, Mortice Kern Systems, GNU Emacs (指定時) |
| 混合 | GNU awk, GNU grep/egrep, Tcl |