ECMAScript 3 正則表達式在設計上有缺陷
ECMAScript 3 有一些主要的正則表達式設計缺陷,如果沒有任何改變,ES4 小組會將一些錯誤傳播到 ECMAScript 4(又名 JavaScript 2)中。
最近,長期的 JavaScript 正則表達式大師 David “liorean” Andersson 寫了幾篇關於我對 ECMAScript 3 正則表達式風格的最大抱怨,即在非參與捕獲組和量化子模式內處理反向引用的方式(參見 ECMAScript 3 正則表達式:一個沒有意義的規範和一個快速的 JS 測驗,適合任何認為他們知道正則表達式的人)。我將避免在這裡重複這些觀點,因為我認為大衛已經很好地闡明了這些問題。作為記錄,我曾計劃將這些問題作為 ECMAScript 4 錯誤提交,但我已經打開了一些 ES4 正則表達式票證,正在等待查看結果,然後再提交更多。
另一個歷史上存在問題的問題是,根據 ES3,正則表達式文字只會導致在運行時為腳本或函數創建一個對象。此問題最常表現為使用 /g
的正則表達式文字 修飾符沒有 lastIndex
在大多數開發人員期望的某些情況下重置屬性。幸運的是,這已經計劃在 ES4 中修復。它是重複次數第三多的 Firefox 錯誤報告這一事實無疑與這一決定有關。
但是回到我最初的咆哮,儘管反向引用處理問題對一些開發人員來說可能不如擁有他們的正則表達式對象的 lastIndex
看似不正常的屬性,它們不再明智或符合開發人員的期望。此外,針對這些問題的 ES3 處理與其他現代正則表達式庫不兼容,並且遠不如替代處理有用(參見例如 Mimicking Conditionals and Capturing Multiple, Optional HTML Attribute Values 了解傳統的 Perl 樣式處理的幾個示例可以好好利用)。
作為相關的咆哮,恕我直言,ECMAScript 4 正則表達式擴展提案錯過了一些關鍵功能添加的機會。以下是 ES4 正則表達式添加的內容,以及一些與兼容性相關的更改以及正則表達式文字跨越多行的能力:
- 字符類集運算——交集和減法,語法靈感來自 java.util.regex。
(?#…)
評論模式。- 命名為捕獲——儘管這似乎沒有經過深思熟慮。但是,看起來 TG1 小組可能願意將語法從規範草案中提議的語法更改為更常見的 .NET/Perl 語法,這將是一種改進。
/y
(sticky) 修飾符——類似於其他幾個庫對\G
的使用 ./x
(擴展)修飾符 - 用於自由間距和註釋。- Unicode 字符屬性 — 但不支持 Unicode 腳本或塊,也不支持
\X
元序列匹配單個字素,這意味著你必須使用\P{M}\p{M}*
. - 支持 Unicode 基本多語言平面之外的十六進製字符代碼 — 通過
\x{n…}
和\u{n…}
,它們是等價的。
有關這些功能的描述,請參閱 ES4 wiki,但請注意,許多關於它們如何工作的更詳細的細節沒有被提及,或者正在其他地方進行討論,例如 [email protected] 郵件列表(此處為外部存檔)或在 ECMAScript 4 問題數據庫中。
除了他們目前提議的實現的一些細節(大部分我已經在其他地方提到過),我認為這些添加非常棒。不過老實說,如果我可以將所有 ES4 正則表達式擴展換成原子組並向後看,我會的。雖然不同的人有不同的優先級是可以理解的,但考慮到原子組具有潛在的顯著性能增強能力和最小的實施負擔,原子組的缺乏尤其是一個重大的遺漏。在 Perl 或其他 Perl 衍生正則表達式庫中發現的可能非常有用的附加功能包括所有格量詞、回溯控制動詞、模式修飾符和模式修飾跨度、條件句、\A
和 \z
斷言、標註、相對反向引用、遞歸、子模式作為子例程、匹配點重置(通過 \K
),重複子模式編號 (?|…)
, 子模式定義 (?(DEFINE)…)
、部分匹配、向後匹配等
由於 ECMA TG1 小組已經聲明他們不再接受主要的規範提案,我預計增加的內容將僅限於已經提出的那些。但是,我希望情況會有所改善,至少通過改進一些現有的 ES3 特性和 ES4 提案。因為我喜歡 JavaScript 和正則表達式,所以我很想看到它們以一種可以與最好的正則表達式庫相媲美的方式結合在一起。也許 ECMAScript 甚至可以在該領域引入一點創新。