為什麼不將 shell glob 視為正則表達式的“方言”?
我經常混淆 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 標准定義:
- 正則表達式及其語法在 POSIX Base Definitions 卷的第 9 章中指定
- 用於文件名擴展的模式在 Shell & Utilities 卷的 Shell 命令語言一章的模式匹配表示法部分的幾個部分中定義。
在 globbing 模式中,標准開始時說
本節中描述的模式匹配表示法用於指定 shell 中匹配字元串的模式。從歷史上看,模式匹配表示法與 XBD 正則表達式中描述的正則表達式表示法相關,但略有不同。出於這個原因,這種模式匹配符號的規則描述是基於正則表達式符號的描述,並進行了修改以考慮差異。
正則表達式有幾種“方言”,例如您提到的 PCRE,但文件名通配模式不能真正說是其中之一。
有幾種模式語言類似於 shell 的文件名通配模式,例如在 SQL 查詢中使用的模式
LIKE
。這些都非常簡單,通常作為匹配字元串位的便捷方式提供。相比之下,正則表達式要復雜得多。您提到“
bash
正則表達式”。bash
shell支持正則表達式,但不支持文件名匹配*。*在 內[[ ... ]]
,=~
運算符執行左側字元串與右側正則表達式的正則表達式匹配。shell 以這種方式支持的正則表達式類型bash
是標準的正則表達式擴展集。有關這方面的更多資訊,請參閱bash
系統手冊。