正規表示式

最後更新: 2022-10-11 18:31:04 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

正規表示式並非單一語言。POSIX BRE、POSIX ERE 和 Perl 相容引擎有所重疊, 但它們的語法、比對規則和可用功能並不相同。

POSIX BRE #

基本正規表示式是 grep 和 sed 採用的歷史語法。

重要規則:

  • 群組使用 \( 和 \);
  • 計數重複使用 \{m,n\};
  • 除非工具加入擴充功能,否則 +、?、| 和 () 都是常值字元;
  • 反向參照使用 \1、\2,依此類推。

BRE 具備可攜性,但因為許多中繼字元需要跳脫,所以較為冗長。

POSIX ERE #

擴充正規表示式更接近現代正規表示式語法:

  • () 用於群組;
  • + 表示一次或多次;
  • ? 表示零次或一次;
  • {m,n} 計算重複次數;
  • | 表示替代。

grep -E 和 sed -E 使用這種形式。POSIX ERE 仍有限制,因為它不支援 惰性量詞、前瞻或後顧。

Perl 相容引擎 #

Perl 相容正規表示式增加了 POSIX RE 所沒有的功能:

  • *? 和 +? 等惰性量詞;
  • 前瞻與後顧;
  • (?:...) 等非擷取群組;
  • 許多引擎支援具名擷取;
  • 更豐富的字元類別語法。

因此,非貪婪比對經常會迫使你切換引擎。POSIX BRE 和 ERE 根本沒有 等效的運算子。

比對行為 #

POSIX 引擎以最左最長比對為規範。即使語法看似相同,此規則產生的結果仍可能 與 Perl 風格引擎不同。

當替代和重複有所重疊時,這一點相當重要,因為引擎可能偏好較長的比對, 而非第一個成功的語法替代項。

錨點也取決於引擎和模式。POSIX 的 ^ 與 $ 表示字串的開頭和結尾, 各工具對行的行為則有所不同;PCRE 風格引擎通常提供獨立的絕對字串錨點和 多行模式。請明確比對常值輸入邊界,而不要假設命令的預設行為。

字元類別並非固定的 ASCII 簡寫。[[:alpha:]] 等 POSIX 方括號類別遵循 目前使用中的語系,而 \w、大小寫摺疊和 Unicode 屬性會隨 Perl 相容 實作及旗標而異。對於以位元組為導向的自動化,請設定已知語系;或明確選擇 引擎的 Unicode 模式。

對於模稜兩可的巢狀重複,回溯引擎可能耗費指數級時間,例如使用 (a+)+$ 比對一段很長且不相符的輸入。處理不受信任的資料時,請限制輸入大小、避免 重疊的替代項和巢狀量詞,或使用線性時間引擎。環視和非擷取群組可以改善 運算式結構,但不會使引擎彼此相容。

實務轉換 #

相同意圖經常需要不同語法:

  • 擷取群組:BRE 使用 \(...\),ERE 使用 (...);
  • 一個或多個數字:BRE 使用 \{1,\},ERE 使用 +;
  • 非貪婪萬用字元:POSIX RE 不支援。

需要可攜性時,請選擇特定引擎,並使用能符合任務需求的最小功能集合。 應根據預期語言和比對語意進行轉換,而非機械式地增加或移除反斜線。

評論

在 GitHub 上閱讀或評論(發表評論需要登入)