Bash

為什麼不將 shell glob 視為正則表達式的“方言”?

  • August 21, 2018

我經常混淆 Bash 3.x shell glob:

?      # Match any single character.
*      # Match any string of characters (up until the asterisk).
[set]  # Match any character in set (but not the entire set itself).
[!set] # Match any character not in set.

使用正則表達式(尤其是PCRE)。

我的問題是為什麼不將這些視為“Bash 正則表達式”(就像我們有“JavaScript 正則表達式”一樣)?

為什麼不將這些視為正則表達式的另一種“方言”?

當然,這將是非正統的,但我不確定沒有任何形式上的邏輯理由不這樣做。

文件名通配模式和正則表達式在一定程度上有語法重疊,但它們以根本不同的方式工作。

正則表達式e將匹配(輸入)字元串hello,而文件名通配模式則e不會。萬用字元模式是隱式錨定的,因此萬用字元模式e相當於看起來像 的正則表達式^e$,但它們的應用可能不同(正則表達式將匹配文本中的完整行,而萬用字元模式通常會匹配單個文件名)。

文件名通配模式也沒有任何特殊字元來限定前一個表達式,例如正則表達式中的*或在正則表達式中。例如,某些 shell 顯然會添加其中的一些內容,例如啟用。?``(...)``|``bash``shopt -s extglob

萬用字元模式與正則表達式有不同的用途。正則表達式主要用於從文本中選擇/匹配字元串,而文件名通配模式主要(但不排他地)用於匹配文件名或從目錄生成現有名稱列表。萬用字元模式用於匹配eg中的字元串case ... esac,但 POSIX shell 從不使用正則表達式從目錄生成名稱列表,除非使用該功能進行擴展

兩種類型的模式都由 POSIX 標准定義:

在 globbing 模式中,標准開始時說

本節中描述的模式匹配表示法用於指定 shell 中匹配字元串的模式。從歷史上看,模式匹配表示法與 XBD 正則表達式中描述的正則表達式表示法相關,但略有不同。出於這個原因,這種模式匹配符號的規則描述是基於正則表達式符號的描述,並進行了修改以考慮差異。

正則表達式有幾種“方言”,例如您提到的 PCRE,但文件名通配模式不能真正說是其中之一。

有幾種模式語言類似於 shell 的文件名通配模式,例如在 SQL 查詢中使用的模式LIKE。這些都非常簡單,通常作為匹配字元串位的便捷方式提供。相比之下,正則表達式要復雜得多。


您提到“bash正則表達式”。bashshell支持正則表達式,但不支持文件名匹配*。*在 內[[ ... ]]=~運算符執行左側字元串與右側正則表達式的正則表達式匹配。shell 以這種方式支持的正則表達式類型bash是標準的正則表達式擴展集。有關這方面的更多資訊,請參閱bash系統手冊。

引用自:https://unix.stackexchange.com/questions/439875