Regular-Expression

什麼表達式會匹配模式 (^0−90−90-9..a-zA-Z一個−和一個−從a-zA-Z+$) 在 grep 命令中?Linux 重擊

  • November 3, 2021

我試圖了解正則表達式(^[0-9]..[a-zA-Z ]+$)在命令中檢測到的確切表達式grep(linux終端)

我知道如果我要編寫以下命令:

grep ^[0-9]..[a-zA-Z] filename.txt

92afg+$會檢測到任何包含表達式的行

grep ^[0-9]..[a-zA-Z]+$ filename.txt

我試圖打開一個新的文本文件,然後只輸入我認為會被檢測到的表達式,但沒有一個匹配,所以我很感激對此的解釋。

+代表“前一個或多個重複”,$是“行尾”。注意與*with 的區別意味著“零次或多次重複”。

所以它基本上意味著:任何以數字開頭的行,後跟兩個任意類型的字元,然後是一個或多個(可能是大寫)字母¹,直到行尾。

(¹要小心,某些語言環境可能不僅有您在 AZ 或 az 中所期望的 26 個字母,例如èŷ取決於語言)

有關正則表達式的良好指南,我強烈建議grymoire 的美麗網站,我也衷心推薦例如sedawk


為什麼不匹配?

+是擴展正則表達式的一部分(否則被解釋為文字+-符號)。

因此,要+用作“一個或多個重複”,請使用-E- 標誌grep並引用正則表達式以避免 shell 特殊字元的任何問題:

grep -E '^[0-9]..[a-zA-Z]+$' filename.txt

讓我們分解一下。首先,請注意此 RegExp 使用“擴展正則表達式”語法 (ERE) - 這+是一個元字元,在預設使用的“基本正則表達式”語法中不起作用grep(這意味著它會匹配自身並需要文字+在那個位置),所以如果你想使用那個 RegEx grep,你需要傳遞這個-E選項。

  • 是將^正則表達式的這個位置與行首聯繫起來的錨點。
  • 是一個字元列表,將匹配落入和之間的排序範圍的[0-9]任何單個(1)字元。究竟包含什麼取決於“整理順序”,其中包括由環境變數確定的。0``9``LC_COLLATE
  • .匹配任何單個字元,因此兩個表示..“任何兩個字元”。
  • [a-zA-Z]再次是一個字元列表,將匹配介於 和 之間的字元( 1)以及介於a和之間的字元。同樣,這意味著什麼取決於整理順序!z``A``Z
  • 意思是“以前的+一個或多個”
  • 是將$正則表達式的這個位置與行尾聯繫起來的錨點。

因此,您的 RegEx旨在(1)匹配任何符合以下條件的行

  • 以任何數字開頭
  • 後跟任意兩個字元
  • 並且只包含直到行尾的字母(但至少一個)。

(1)關於它可能實際做什麼,見下文

一些筆記

  1. 在您的範例中,您使用不帶引號的正則表達式。grep這意味著任何字元在傳遞給命令之前都可以由 shell 解釋。如果您的模式包含$或通配字元(*?字元[...]列表!),shell 可能會嘗試執行變數擴展(從而替換您的 RegEx 的一部分)或將通配模式擴展為可能的多個文件名,以便最終您會有更多參數在您最初打算的命令行上。對 shell 來說特殊的其他字元(>#;)可能會導致更意想不到的行為。你應該使用
grep -E '^[0-9]..[a-zA-Z]+$' filename.txt

反而。-x請注意,您可以通過使用標誌強制“整行”匹配來擺脫打開和關閉錨點:

grep -x -E '[0-9]..[a-zA-Z]+' filename.txt
  1. 包含範圍(例如a-z)的字元列表很危險,因為它們可能無法給出您的想法。天真地人們可能期望它們匹配位於 ASCII 表上開始和結束字元之間的所有字元,但這僅適用於C語言環境。在其他語言環境中(特別是在通常設置的系統語言環境中,例如en_US.UTF-8),排序順序類似於aAbB ... zZ這樣a-z也將匹配大多數大寫字母。此外,匹配實際上不是在單個字元級別上,而是在“排序元素”級別上,這意味著在某些語言環境中,甚至幾個字母的組合也可能匹配(例如dzs在匈牙利語中)!看到這個答案(或者,一般來說,@Stéphane Chazelas 關於模式匹配的大多數答案)以獲得更多洞察力。如果您想確保您的範圍有效,請至少為給定命令設置排序順序
LC_COLLATE="C" grep -E ' ... ' filename.txt

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